View RSS Feed

Development Team Blog

RunProgram: Possibly the most misunderstood command ever

Rate this Entry
This poor command has been around in Visual DataFlex for as long as anyone can probably remember. Every VDF developer knows about this command, yet it's so often misunderstood and a frequent subject in the forum. It's actually pretty well documented, the documentation was even improved a few revisions back when the command was also enhanced for smoother operation in Vista. But probably because it's so well known, you rarely consult the documentation. So I'll provide a quick primer for this command, you don't even have to admit you've read it, but hopefully it will help the next time you encounter a problem using RunProgram.

First let's debunk a common myth and misconception that the program arguments are lowercased. This is simply not true, but nonetheless a common side effect of using RunProgram incorrectly. Ignoring the optional Wait/Background parameter, the RunProgram command takes two separate parameters. That's right, two separate parameters. The executable program file path (.exe) and the optional program arguments separately. The documentation actually mentions this several times, yet it's by far the most common misconception.

RunProgram "TotalHoursForEmployee.exe"    "EmployeeId=42"
For some arguably arcane legacy reason the program path (the first parameter) is automatically lowercased. (Way back in the day it was done to simplify DOS/Unix portability). But the second parameter which contains the program arguments is of course left untouched and passed on verbatim. But many people have realized that sometimes you can squeeze both the program file and arguments together into the first parameter to RunProgram, and it sort of almost works anyway. That is, it often kind of works except it will obviously lowercase the program arguments along with the program file path, hence this common misconception. The solution is of course very simple, just use the command as it was meant to be used, passing the program arguments in the second parameter to RunProgram, and all will be fine.

RunProgram Wait "TotalHoursForEmployee.exe"    "EmployeeId=42"


Move "notepad.exe" to sProgram
Move "C:\Autoexec.bat" to sArgs
RunProgram Wait sProgram  sArgs
The second most common problem developers face with RunProgram is that it doesn't find the executable program file. If the program is not located in the current working directory or along the system search path, it won't find it and it won't run (a variation of this is that it perhaps doesn't find the file to to open that was passed as a program argument). Of course, we all knew this as we've all run into this problem countless times in a command prompt window. But when using the RunProgram command this simple detail often eludes us.

RunProgram Wait "C:\MyCoolProgram\TotalHoursForEmployee.exe"    "EmployeeId=42"
Lastly, a little known addition to this command is the new Shell parameter, which can be used in place of Wait. The documentation explains it best:
If the shell option is included, the command will use the operating system shell to start the program. In Windows Vista and later, this is specifically used to enable the Vista UAC credential (user consent) prompt when starting programs that require elevated administrator privileges. Note that when the shell option is used, any program arguments must be placed in program-arguments, and cannot be mixed with program-name.

The shell option can also be used to launch a program associated with a specified document/file, without specifying the executable file name. This is often used to open a document, such as a .doc file or .pdf file. In such case the document should be specified instead of program-name.
For more advanced options and finer control you can of course use the Win32 API directly either via ShellExecute, or one of the excellent open source packages available at Hopefully this little primer should clarify the common misconceptions with RunProgram. And of course, there's always the documentation for the RunProgram command itself.