7
votes

I don't find in the help an exhaustive explanation of the difference between Shellexec and Exec. Is the

Shellexec('','program.exe',params,'',SW_HIDE,ewWaitUntilTerminated,ResultCode) 

equivalent to

Exec('program.exe',params,'',SW_HIDE,ewWaitUntilTerminated,ResultCode) 

when working with exe files? Of course, when I want execute a file different from exe or batch, use Shellexec.

Sometimes, however, I can't get my istruction to work correctly neither by Shellexec nor Exec. The only solution that always work is to write a batch file and run it via shellexec. Personally I don't like this solution because I have to deal with a temporary file and I don't trust the resultcode obtained. Now I'll have to get back to the batch file solution, because I don't know how to get this instruction work: (the error is that it raises the instruction fails if the destination file is not already present, while in command prompt the instruction works even the destination file does not exist).

mysqldump := 'C:\Program Files (x86)\MySQL\MySQL Server 5.0\bin\mysqldump.exe';
params := '-uroot -ppassword myschema>C:\myappdir\backup\newbackup.sql'; 
//the destination folder exists, the file newbackup.sql does not exist      
Shellexec('',mysqldump,params,'',SW_HIDE,ewWaitUntilTerminated,ResultCode);

I am working on Windows 7 64 bit, the program (an Inno Setup installer) is run with administrative rights

3
Definitely use the {pf32} constant instead of C:\Program Files (x86). It will returns you the correct path to the 32-bit program files directory. I think it might be the cause of your problem, but hard to say. You can also check if the file exists with the FileExists function before you try to execute it. - TLama

3 Answers

7
votes

In that situation in Inno Setup, the two calls are pretty much identical. If however, the setup is running at the lowest priviliges and you try and run a process that requires elevation, ShellExec() will allow it to prompt whereas Exec() will fail.

The differences between the two appear when passing single monolithic command lines, passing non executables, or when using verbs other than "open".

Note that neither function will allow you to run commands or operations provided by the command interpreter like the redirection operator (... > ...). These commands will need to be passed to {cmd} to be able to run.

Here's some air code:

mysqldump := 'C:\Program Files (x86)\MySQL\MySQL Server 5.0\bin\mysqldump.exe';
params := '-uroot -ppassword myschema';
dumpfile : = 'C:\myappdir\backup\newbackup.sql';

command := AddQuotes(mysqldump) + ' ' + params + ' >' + AddQuotes(dumpfile);
Exec(ExpandConstant('{cmd}'), '/C ' + command, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); 
3
votes

Have you considered using CreateProcess to start the process? This call provides a few extra options to control the resulting process, and also may handle the paramaters passed better.

3
votes

If you can use the JEDI JVCL library, they have a nice component that encapsulates CreateProcess for you:

http://jvcl.delphi-jedi.org/

Look at the JvCreateProcess and JvCreateProcessExtended components. The JEDI JVCL is free and open source and is released under the Mozilla Public License.