Ultimate MS Outlook Editor
At my work, I'm required to use Microsoft Outlook for exchanging email with my co-workers. At home, I use Mutt on FreeBSD, and have grown to really love the lightning-fast responsiveness, immunity to virusses, and easy scriptability of this tiny text-based mail reader.
I'm going to tell you one solution, just so I can tell you another one :)
It's possible to use Mutt with Microsoft Exchange:
- Set up IMAP on your Exchange server. This was already done here.
- Install a copy of Cygwin, including Python.
- Either set up Mutt to access IMAP on Exchange directly, or do what I prefer to do: download and set up offlineimap. This IMAP-to-Maildir synchronization utility is excellent.
- First, you need to run the "rebaseall" utility so that Python doesn't dump with traceback when you try to run offlineimap. You can't rebaseall if you're trying to do it from an rxvt window -- you need to be using the cmd-based Cygwin shell for it to finish without an error.
- Then you need make sure your .offlineimaprc file specifies "Curses.Blinkenlights" as the first available interface -- the TK interface, on Win32, just hangs.
- You can't use offlineimap on a non-managed Cygwin mount. The reason is that the Maildir specification uses the ":" character, which is a big no-no in Windows-land. The solution is to use this command:
$ mount -f -s -b -o managed "d:/tmp/mail" "/home/of/mail"
substituting the windows-path directory you wish to use for mail for the "d:/tmp/mail" above, and the mount point you wish to put it on instead of "/home/of/mail". - Once you have IMAP-to-Maildir synchronization going to your local PC, then you're good to go with offline IMAP stuff and Mutt. Follow the usual directions for configuring Mutt to use the Maildir you've set up, paying particular attention to choice of outbound mailer (probably ssmtp).
So I installed Python and the Win32 extensions for Python, then linked this script on my quickbar in Windows, conveniently right next to Outlook:
#!/bin/env python
'''
outlook.pyw (OutLook editor launcher) -- allows one to edit an open e-mail
mesg from Outlook using Emacs or *Vi* rather than "Notepad--". :-)
NOTE: requires Python 1.6 and newer (use of string methods)
created by John Klassa (klassa at employees.org) on 2001 May 29
updated by Wesley Chun (cyberweb at rocketmail.com) on 2002 Feb 28
$Id: outlook.pyw,v 0.2 2002/08/28 18:04:06 wesc Exp wesc $
'''
from os import spawnv, P_WAIT, unlink
from tempfile import mktemp
from Tkinter import Tk, Button, Frame, Label
from Tkconstants import *
from win32com.client import Dispatch
def launch():
'''launch() spawns your favorite editor to edit the Outlook compose
window (either new or reply), then returns that data to Outlook...
change the 'ed' variable to switch editors.'''
# Get a handle to Outlook.
o = Dispatch("Outlook.Application")
# Work our way down to the reply (a "MailItem").
insp = o.ActiveInspector()
if insp == None: return
item = insp.CurrentItem
if item == None: return
# Grab the message body in the reply.
body = item.Body
# Write the body... need to "encode" the string because Outlook uses
# Unicode with bunch of unprintables (ASCII chars > 128). Also, since
# we are going from DOS2UNIX2DOS, we have the \r\n vs \n issue, re-
# sulting in those fabulous ^M characters. A persistent, bound-to-a-
# key Emacs macro takes care of that nicely, but the solution imple-
# mented here is to just wipe the '\r's now, then add them back when
# we reread this file back before returning the body to Outlook.
tmp = mktemp() # generate a unique tmp filename
fh = open(tmp, "w")
fh.write(body.encode('ascii', 'ignore').replace('\r\n', '\n'))
fh.close()
# Launch editor to edit the file (should make this configurable).
#ed = r"d:\emacs-20.7\bin\emacs" # emacs editor binary
ed = r"c:\vim\vim62\gvim.exe" # *vi* editor binary
spawnv(P_WAIT, ed, [ed, tmp])
# Read edited file back into memory, restore '\r's, and kill tmp file.
fh = open(tmp)
body = fh.read().replace('\n', '\r\n')
fh.close()
unlink(tmp)
# Store it as the body of the reply. Note that we are merely
# sending this data back to Outlook -- it does not prevent MS from
# mucking with your message. For example, it may add your signature
# again, or it may remove newlines. MS software... what can you do?
item.Body = body
# Create the Tk(inter) GUI app with the appropriate label and buttons.
if __name__=='__main__':
tk = Tk()
f = Frame(tk, relief=RIDGE, borderwidth=2).pack()
Label(f, text="Outlook Edit Launcher v0.2").pack()
Button(f, text="Edit", fg='blue', command=launch).pack(fill=BOTH)
Button(f, text="Quit", fg='red', command=tk.quit).pack(fill=BOTH)
tk.mainloop()
I now click Outlook, then click my outlook.py script. I minimize the annoying black cmd window that comes up (anybody know how to get rid of this?), and I now have a little Python/TK window with a convenient "edit" button on it. When I compose a message in LookOut, I click this "edit" button, and up pops gvim 6.2, ready for me to type the message. When I'm done typing it, I just write-quit out of gvim, and the text pops up in my Outlook compose window.
Convenient! Well, for a UNIX-geek at least.
Anyway, I'm still torn. Do I really need to use Outlook here? Realistically, I have maybe one meeting a week that I need to keep track of, and that's easily done in my Palm. Maybe I should just use Mutt in Cygwin on a managed mount? Who knows, but both are valid choices. And in a world where MS wants you to only use MS products, and those products are funkily generic and slow, it's nice to have choices.
Well, you brought up a very g
Well, you brought up a very general topic. So I'm going to give generic advice for setting up a small office network on the cheap.
The first thing to realize is that "freeware", or "open source" is only free if your time is worth nothing. If you know nothing about what you're doing, you'll be paying a consultant to do it right regardless of what platform you choose. You can do it "on the cheap" on your own, but you'll be learning a lot as you do so :)
There are several basic components to any office setup, some of which may be optional depending on your situation and type of business:
- Infrastructure:
- Electronic Mail System
- Shared calendaring system
- Telephone (PBX) System
- Fax system
- File-Sharing
- Web presence (lots to this, depending on what you wish to do)
- Switch, router, and firewall
- Documentation management
- Customer Relationship Management
- Web browser
- Email reader
- Office suite
- Domain-specific applications (Photoshop for the artist, Lightwave for the modeler, etc.)
- Accounting package(s)
- Project management
With all of these, you can pick-and-choose where you want technology to assist you, and where you wish to do things by hand. You can also choose to outsource much of it, pick a closed-source application, or pick an open-source app that you can modify to suit your needs.
My default rule in new buildouts is to use open-source ("free" or "libre") software wherever possible. I can make that default choice without additional justification if it's capable of meeting the needs of the client. If I must choose a proprietary application (such as Microsoft Exchange), I then need to give justifications for that choice.
For desktops, if it is feasible, I would choose GNU/Linux. Which distribution is probably irrelevant, but for ease of updating, and due to some idealistic concerns regarding free software, I would probably pick Debian.
If I had to choose between MacOSX and Windows, I would pick MacOSX in a heartbeat. At its core, it is a UNIX-based operating system. It is also less popular than MS Windows, and in this age of monoculture computer virusses, that alone is an excellent justification. It has all the domain-specific apps people need in a creative workshop, runs on standardized hardware that, while expensive, has a much lower failure rate than commodity PCs, and has a definite sex appeal :)
On the server side, I'd buy one really fast, capable dual-processor PC with 2 GB+ RAM, a 64-bit processor (AMD or Intel), running GNU/Linux. Possibly, if you want to stay an all-Mac shop, a Mac rackable G5 server would be a good choice for this, too. Run all the critical services on this one box, and maybe set up a second one with an identical configuration so you have a backup in case the primary fails.
I could write an essay about this, so I'll stop now.
--
Matthew P. Barnson
The MS Way
Try this:
- Copy the following into a file and name it 'launchvim.vbs'
Option Explicit Private Sub launch() Const TemporaryFolder = 2 Dim ws, ol, insp, item, body, fso, tempfile, tfolder, tname, tfile Set ol = CreateObject("Outlook.Application") Set insp = ol.ActiveInspector If insp Is Nothing then Exit Sub End if Set item = insp.CurrentItem If item Is Nothing then Exit Sub End if body = CStr(item.Body) Set fso = CreateObject("Scripting.FileSystemObject") Set tfolder = fso.GetSpecialFolder(TemporaryFolder) tname = fso.GetTempName Set tfile = tfolder.CreateTextFile(tname) tfile.Write( Replace( body, Chr(13) & Chr(10), Chr(10) ) ) tfile.Close() Set ws = WScript.CreateObject("WScript.Shell") Wsh.Echo( "c:\vim\vim62\gvim.exe " & tfolder.Path & "\" & tname ) ws.Run "c:\vim\vim62\gvim.exe " & tfolder.Path & "\" & tname ,4, true Set tfile = fso.OpenTextFile(tfolder.Path & "\" & tname, 1 ) item.body = Replace( tfile.ReadAll, Chr(10), Chr(13) & Chr(10) ) tfile.close() fso.DeleteFile( tfolder.Path & "\" & tname ) End Sub Call launch() - In Outlook, Go To Tools->Macros->VB Editor (Make sure your Security settings for Outlook are set to Medium)
- Add a new module, and paste this into it
Sub LaunchVIM() Dim windir As String windir = Environ("WinDir") Shell (windir & "\system32\cscript.exe " & windir & "\system32\launchvim.vbs") End Sub - Open a new Outlook mail message
- Click View->Toolbars->Customize
- Under the Commands tab, Select Macros on the left, and drag the macro you just created to the Outlook toolbar in your newly opened mail dialog.
EDIT by matthew: cleaned up formatting for slightly easier readability.
SWEET!
Pretty sweet, dude. I now have a "Project1.LaunchVIM" button on my toolbar. Unfortunately, setting security to Medium violates our corporate security policy. So I reset it back to High after installing the button, and the button continues to work fine.
So, for future security-conscious readers, set to Medium to install the script, then back to High and your script will continue to run without problems. How long did it take you to whip that out, Weed? I know next to nothing about Visual Basic, but it is visually much cleaner (and easier to install) than a separate Python window with an "EDIT" button :)
--
Matthew P. Barnson
Uh-oh
Matt
The security feature of the macros takes place after the next restart, so more than likely the next time you open Outlook your button won't work.
I'll look into signing the code so it works with High. You may have to install my company's cert authority tho, 'cause I'm not paying Veri$ign to sign it.
As for VBScript, it's not hard. http://msdn.microsoft.com/ has a bunch of information on it, but, as with all Microsoft, you have to learn how to search for it.
Look here:
http://www.microsoft.com/technet/prodtechnol/office/office2000/maintain/security/o2ksec.mspx
Roger that
Yeah, just fired up Outlook again, and the button does nothing. Durn.
For now, I'm continuing to use my offlineimap/Mutt/Cygwin solution. It works very well to keep the folders synchronized, but stuff like seeing other users' folders just doesn't work at all, so I have to keep Outlook around.
--
Matthew P. Barnson
Change the .py to .pyw
Getting rid of the python console is easy - change the file extension. The app will work and the console will not be spawned.
.py to .pyw
Changing the file extension to .pyw worked like a champ for getting rid of the console window; thanks for the tip!
--
Matthew P. Barnson
Restoring the text format
Hi Weed, this script works well for me. It is very useful and productive for Vim fans like me! I am looking for one more feature. Right now, when I return back from my Vim session the file type is set to 'rich text' irrespective of the state before editing in vim. Is it possible to restore the text format. If that is not possible, how to set it to 'plain text' which makes more sense when we edit using vim (the nice indentations will show up the same way in outlook)
Thanks
--Mahesh N
How to sign it
See this page
for how to sign the thing. Working for me now.
--
Paul Wright
EDIT by matthew: linked.
Mail format
Unfortunately, this is a change you have to make in Outlook, not in your configuration for using VIM.
In Outlook, go to the Tools menu and select Options. Click the "Mail Format" tab, and change the "Compose in this message format" from "Rich Text" to "Plain Text". The problem is then solved, and you have your nice indentation and mail config.
I'm in this same boat again today, since I'm working a new job where they use Outlook exclusively. And, in this case, Outlook is extremely tied-in to their basic management systems, so using Mutt to the exclusion out Outlook is no longer an option (sigh)... So I came back to this page this morning to remember how I did it!
Anyway, changing those options will do the trick. The one annoyance left is that with the latest patches to Outlook, every time I launch this I get a prompt saying "A program is trying to access your Address Book", and I have to click "Yes" to allow it to run. It's only one extra click, but I do this in part for convenience. I've been digging around trying to figure out how to turn this off for a signed, truested vbscript, but no luck.
However, the tips above on signing your own code work great to make it work appropriately, with the exception of that annoying pop-up every time I compose a mail message.
The price I pay for being a UNIX geek, I guess... maybe I'll go back to using Mutt on Cygwin for email, and just use LookOut for calendars, contacts, etc.
--
Matthew P. Barnson
what if we don't have gvim installed?
I use non-gui version of vim under Windows XP + cygwin, and I am not willing to install another windows version gvim at the moment. Is it possible to tailor these scripts so that it works under such environment?
I am always wanting tweaks such that whenever windows calls for a text editor, it invokes rxvt + vim, is this possible?
Thanks,
Jindan
Yes, replacement
Jindan,
Yes, replacement is trivially easy in each of these scripts in order to use the cygwin version of vim instead of the native Win32 gvim. Simply everywhere it currently calls c:\some_path\bin\vim, replace it with c:\your_cygwin_path\bin\rxvt -e vim.
For instance, in my case, my Cygwin root is in d:\cygwin. I would replace this line:
ed = r"c:\vim\vim62\gvim.exe" # *vi* editor binary
with this one:
ed = r"d:\cygwin\bin\rxvt.exe -e vim" # *vi* editor binary
Just tested it, done and done. So the Python version is figured out; you'd need to adjust it similarly if you were to use Weed's Visual Basic version on the parent page. I'm not using either one anymore, at the moment, because I'm so sick of Outlook. I went back to using OfflineIMAP + Mutt on a Cygwin managed mount because it's so much faster, and I can run it remotely without having to use some sort of remote desktop. If I get an appointment in my inbox that requires their synchronization tool, I note the time of the appointment in my Palm Pilot, and next time I'm in the office I might fire up Outlook to confirm the appointment (or just show up; people around here rarely seem to care if you actually RSVP for the meeting or not).
Curiously, my new company's Exchange server doesn't create nearly the havoc with offlineimap that the old one did. I wonder if they improved their IMAP support in the latest version?
--
Matthew P. Barnson
That is so cool!
This is what I did, first I created vim.bat in c:\program files\cygwin\bin with this line:
start rxvt -sr -sl 2500 -geometry 90x30 -fg grey70 -bg midnightblue -fn "Lucida ConsoleP-16" -e vim %1
Then I changed the View Source program from Notepad to vim.bat, worked out like a charm! Since many of the IE temp file doesn't have an extension file name, I need to manually type
set syntax=html
to enable syntax highlighting each time. Trying to figure out a workaround now.
Weed's code doesn't work out (yet), when I press the macro button, the screen flashed as if something happening, but then nothing. Is there a log that I can check in VB editor or Outlook so that I can tell what happened?
syntax highlighting
Try adding these lines to your $HOME/.vimrc file (this varies according to installation, the easiest way is to just do "vi ~/.vimrc" from a cygwin shell):
"turn on syntax highlighting
:syntax on
Now it's possible that vim may not recognize your terminal type. In order to work around this (like if syntax highlighting won't turn on from this one addition to your .vimrc), then try adding these to your ~/.vimrc:
"fix inability to read term type
:set term=xterm-color
--
Matthew P. Barnson
I think the problem is with ...
That the IE temporary files are sometimes without an explicit extension name, i.e. .html, .htm, etc., thus vim can't find a proper syntax highlighting scheme, even though I have "syntax on" set in my .vimrc file.
Okay, the prolem is solved by ...
modifying my vim.bat as followed:
start rxvt -sr -sl 2500 -geometry 90x30 -fg grey70 -bg midnightblue -fn "Lucida ConsoleP-16" -e vim -c "set syntax=html" %1
Thanks, Matt!
syntax=mail
You'll get even better results with syntax highlighting if you do a:
vim -c "set syntax=mail" %1
Vim's very smart about email syntax, understanding quoting and such. Since I prefer a dark background with light text, I'd add this to my .vimrc as well:
:colorscheme murphy
Other light-on-dark colorschemes that work well are "torte", "evening", and "ron".
Good luck!
:wq!
--
Matthew P. Barnson
Alternatively
Since Windows runs programs based on extension and not MIME-type, setting the first line in the script to:
#!c:\python24\pythonw.exe
will do the same thing.
Python for Windows associates *.py with python.exe and *.pyw with pythonw.exe.
The Python code strips accented letters from Outlook
fh.write(body.encode('ascii', 'ignore').replace('\r\n', '\n'))
likely is the reason that accented letters like é in Gérard end up being dropped :-(
This severely limits an otherwise very good call to VIM for Outlook.
Any fix?
encoding...
I'd think replacing "ascii" with a Unicode encoding such as "Latin-1" might do the trick, or, more likely, eliminate the body.encode call entirely and try just doing an fh.write. Unfortunately, I've stopped using this program for "real" work, so I don't have a way to test it.
You'll also have to make sure your Vim is set up to handle Unicode, which is an area where I have to claim utter ignorance :)
Additionally, I don't know that the whole stripping \r\n thing is even necessary in the Windows version of Vim today. The one I'm running now handles DOS-formatted files without a hiccup.
--
Matthew P. Barnson
Weed's code
It doesn't work for me (yet). I tried debugging the script and found that the GetInspector methor returns "Nothing" - I have Microsoft Outlook 2003. I went to outlookcode.com and obtained a few test scripts - all of them exit with the same result - GetInspector returns nothing. Does anyone have any clues to offer?
Thanks in advance,
Girish
Problem with VBS
Hi,
I successfully created the launchvim.vbs script and the acompanying VB Makro. But vim doesn't start when clicking on the macro-button in the toolbar. Does anyone have a clue?
I'm using Outlook 2003 and VIM 7.0
Here's the new version
All,
I changed the code up a bit. Here are the new steps.
1) In Outlook, click Tools->Macro->Visual Basic Editor
2) Under Tools->References, make sure Microsoft Scripting Runtime is selected. Close out of the dialog
3) Either create a new module or use and existing one
4) Paste the following code into the module:
Option Explicit
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&
Sub LaunchVIM()
'Dim windir As String
'windir = Environ("WinDir")
'Shell (windir & "\system32\cscript.exe " & windir & "\system32\launchvim.vbs")
Const TemporaryFolder = 2
Const VIMLocation = "C:\Program Files\Vim\vim70\gvim.exe"
Dim ol, insp, item, body, fso, tempfile, tfolder, tname, tfile, appRef, x
Set ol = Application
Set insp = ol.ActiveInspector
If insp Is Nothing Then
Exit Sub
End If
Set item = insp.CurrentItem
If item Is Nothing Then
Exit Sub
End If
body = CStr(item.body)
Set fso = CreateObject("Scripting.FileSystemObject")
Set tfolder = fso.GetSpecialFolder(TemporaryFolder)
tname = fso.GetTempName
Set tfile = tfolder.CreateTextFile(tname)
tfile.Write (Replace(body, Chr(13) & Chr(10), Chr(10)))
tfile.Close
ExecCmd VIMLocation & " " & Chr(34) & tfolder.Path & "\" & tname & Chr(34)
Set tfile = fso.OpenTextFile(tfolder.Path & "\" & tname, 1)
item.body = Replace(tfile.ReadAll, Chr(10), Chr(13) & Chr(10))
tfile.Close
fso.DeleteFile (tfolder.Path & "\" & tname)
End Sub
Public Sub ExecCmd(cmdline$)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ReturnValue As Integer
' Initialize the STARTUPINFO structure:
start.cb = Len(start)
' Start the shelled application:
ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
' Wait for the shelled application to finish:
Do
ReturnValue = WaitForSingleObject(proc.hProcess, 0)
DoEvents
Loop Until ReturnValue <> 258
ReturnValue = CloseHandle(proc.hProcess)
End Sub
Now follow the above intructions on creating a toolbar button that launches the Macro "LaunchVIM"
This method keeps everything in VBA and strips out the VBScript external application as well as the WSH junk.
This post used massive amounts of cut-and-paste programming from examples provided at the MS MSDN site. All the answers are there, however finding them is the trick. ;)
My $.02
Weed
Colorized!
And, of course, the preceding code... colorized!
Yeah, I'm useless. But I like coloring books.
Option Explicit
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&
Sub LaunchVIM()
'Dim windir As String
'windir = Environ("WinDir")
'Shell (windir & "\system32\cscript.exe " & windir & "\system32\launchvim.vbs")
Const TemporaryFolder = 2
Const VIMLocation = "C:\Program Files\Vim\vim70\gvim.exe"
Dim ol, insp, item, body, fso, tempfile, tfolder, tname, tfile, appRef, x
Set ol = Application
Set insp = ol.ActiveInspector
If insp Is Nothing Then
Exit Sub
End If
Set item = insp.CurrentItem
If item Is Nothing Then
Exit Sub
End If
body = CStr(item.body)
Set fso = CreateObject("Scripting.FileSystemObject")
Set tfolder = fso.GetSpecialFolder(TemporaryFolder)
tname = fso.GetTempName
Set tfile = tfolder.CreateTextFile(tname)
tfile.Write (Replace(body, Chr(13) & Chr(10), Chr(10)))
tfile.Close
ExecCmd VIMLocation & " " & Chr(34) & tfolder.Path & "\" & tname & Chr(34)
Set tfile = fso.OpenTextFile(tfolder.Path & "\" & tname, 1)
item.body = Replace(tfile.ReadAll, Chr(10), Chr(13) & Chr(10))
tfile.Close
fso.DeleteFile (tfolder.Path & "\" & tname)
End Sub
Public Sub ExecCmd(cmdline$)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ReturnValue As Integer
' Initialize the STARTUPINFO structure:
start.cb = Len(start)
' Start the shelled application:
ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
' Wait for the shelled application to finish:
Do
ReturnValue = WaitForSingleObject(proc.hProcess, 0)
DoEvents
Loop Until ReturnValue 258
ReturnValue = CloseHandle(proc.hProcess)
End Sub


That's so 1990s
Matt, c'mon man, who isn't using Mutt in Cygwin on a manager mount these days? Get with the times dude.
Here's a question: say a small firm is setting up an office for 5 employees. The set up is going to be a server-client network (no shared apps). Do you recommend going with a MS Windows or Mac OS system? Are there choices in buying out-of-the-box or configurable servers and workstations that can house popular software, don't cost an arm and a leg and give choice?
Wondering if you can go out and buy the computing pieces and then run a freeware OS and pick and choose your components...and if it makes compatibility and cost sense...
BTW -- I'm not trying to diminish the genius of your original post, it's just that I don't understand it. :)