7

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

Deanna
  • 23,876
  • 7
  • 71
  • 156
lib
  • 2,918
  • 3
  • 27
  • 53
  • 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 May 01 '12 at 19:04

3 Answers3

7

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); 
Deanna
  • 23,876
  • 7
  • 71
  • 156
  • 2
    +1, the first answer considering the InnoSetup tag and the question itself! But the *It also handles the elevation if the process needs it where CreateProcess() doesn't* is a little bit confusing here, both functions `ShellExec` and `Exec` uses the same rights as setup itself. – TLama May 01 '12 at 18:53
  • 4
    Ah, I missed the inno-setup tag, in that case yes, they're pretty much identical, and come doen to parsing. IF howwver, the setup is run as a limited user, or `ShellExecAsOriginalUser` then it will ask for elevation if required. `Exec()` will fail in that case. – Deanna May 02 '12 at 09:47
  • 2
    Thank you! Now I understand why it did not work! Sorry for the Delphi tag in first position, maybe it was misleading – lib May 04 '12 at 17:00
3

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.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • 1
    Thank you, I haven't tried that instruction before. I haven't a found a CreateProcess instruction in Innosetup. Anyway, I think it may be useful in my Delphi projects. In the process of learning the use of CreateProcess I came across [this question](http://stackoverflow.com/q/343476/1136458). My instruction still doesn't work, maybe because of the redirection of the output. – lib Apr 29 '12 at 20:35
  • 1
    You may not need redirection and the default behaviour might just do fine, have a try without the `or STARTF_USESTDHANDLES` and creating/setting the handles. – Stijn Sanders Apr 29 '12 at 21:16
3

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.

Robert Oschler
  • 14,153
  • 18
  • 94
  • 227