cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
tier_3
Level 4

Issue using LaunchAppAndWait with LongPathToQuote in IS 2011

To illustrate this issue, I created a batch file called "test-launch.bat" which will print out the current working directory.


cd > "c:\test long path\test-launch.txt"


I used the code below on both IS 2010 and IS 2011.

spath = "C:\\test long path\\test-launch.bat";
LongPathToQuote(spath,TRUE);
LaunchAppAndWait(spath,"",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);


The output file c:\test long path\test-launch.txt for IS 2010 shows:
C:\test long path

The output for IS 2011 show:
C:\InstallShield 2011 Projects\test-project\Media\Release 1\Disk Images\Disk1

The behaviour of LaunchAppAndWait when used with LongPathToQuote has changed in IS 2011 where the current working directory will be changed to the directory where the setup.exe was launched.

Is this a bug in IS 2011?
Labels (1)
0 Kudos
(6) Replies
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

While there may have been code changes in the InstallScript engine that affect a running setup's working directory, LaunchAppAndWait did not make any guarantees about the work directory that a launched process will be set as unless LAAW_OPTION_CHANGEDIRECTORY was passed, which temporarily changes the setup's working directory to the path of the new process being launched.

If you would like specific control of the working directory for a new process, the LaunchApplication function should be used instead of LaunchAppAndWait (LaunchApplication supercedes LaunchAppAndWait), which provides for setting the working directory with the szDirectory parameter.

Note that LongPathToQuote only ensures that a path containing spaces is correctly quoted. It is not affected by any system or current process state.
0 Kudos
tier_3
Level 4

The reference for the LaunchAppAndWait() function in the IS 2011 document shows that it passes in the LAAW_OPTION_CHANGEDIRECTORY option, so it should temporarily update the currently working directory to the directory where the command is executed.

http://kb.flexerasoftware.com/selfservice/microsites/search.do?cmd=displayKC&docType=kc&externalId=InstallShield2011-mergedProjects-installshield17langref-LangrefLaunchAppAndWaithtm&sliceId=&docTypeID=DT_MACROVISIONHELPNET_1_1&dialogID=94578420&stateId=0%200%2094580152

I have narrowed the problem down further.
If I run the following code:

LaunchAppAndWait("\"C:\\test long path\\test-launch.bat\"","",LAAW_OPTION_WAIT|LAAW_OPTION_SHOW_HOURGLASS|LAAW_OPTION_HIDDEN);


The results will be different between IS 2010 and IS 2011.
The output file c:\test long path\test-launch.txt for IS 2010 shows:
C:\test long path

The output for IS 2011 show:
C:\InstallShield 2011 Projects\test-project\Media\Release 1\Disk Images\Disk1

So it seems like passing in two double quotes in the command will change behaviour of the current working directory path in 2011.
Will this be fixed sometime in the future?
0 Kudos
joshstechnij
Level 10 Flexeran
Level 10 Flexeran

This issue isn't directly related to the InstallScript engine. For IS 2011, the InstallScript engine was changed to be fully Unicode compatible. As such, all Win32 API calls the engine makes in internal script code were updated to use the Unicode versions of these APIs (otherwise, InstallScript projects would still not be Unicode compatible).

For the LAAW_OPTION_CHANGEDIRECTORY option, the code for LaunchAppAndWait (LaunchApplication) parses the path passed in the szProgram parameter to obtain the path of the program to launch. This path is then passed to ChangeDirectory, which is just a wrapper around the Win32 SetCurrentDirectory API. In previous versions of InstallShield, the ANSI version of this API was called. Starting with 2011, the Unicode version is called. Previously, the parsed path (the example path would literally be "C:\test long path\) was passed to SetCurrentDirectoryA and the call would succeed. Now, the same path passed to SetCurrentDirectoryW will fail with status ERROR_INVALID_NAME ("The filename, directory name, or volume label syntax is incorrect.") due to the leading quote.

Essentially, the current directory is not being changed because Windows will not accept a path with quotes in it when calling SetCurrentDirectoryW. The difference is the SetCurrentDirectoryA function appears to handle the path string slightly differently (probably because it has to convert it to Unicode and then call SetCurrentDirectoryW).

There's a couple of things to point out here:
- The path passed to szProgram for LaunchAppAndWait should not be quoted with LongPathToQuote.
- When the program to launch is passed in szProgram, and the call to LaunchAppAndWait does not use LAAW_OPTION_USESHELLEXECUTE, the szProgram string will be quoted by LongPathToQuote anyway, after the current directory processing is finished (the program and command line are concatenated into one string and passed to the lpCommandLine parameter of the Win32 CreateProcess API).
- If the program and parameters were all passed in the szCmdLine parameter and the program path contained spaces, the string should be quoted with LongPathToQuote (see the LaunchApplication documentation for the szCmdLine parameter).
- The LaunchAppAndWait function has been superceded by LaunchApplication function. LaunchApplication provides for much flexibility in specifying the working directory for a program to launch.

To resolve this issue, either LongPathToQuote should not be called when specifying a program to launch with the szProgram parameter for LaunchAppAndWait, or LaunchApplication should be used instead for greater control of the new process's working directory.
0 Kudos
tier_3
Level 4

I appreciate the detailed response.
I will update the script accordingly. Thanks.
0 Kudos
maforshaw
Level 5

I also appreciate the explanation as the help file is not very good for this function. It needs to say when quotes are needed.

This is especially important because of the way CreateProcess and ShellExecuteEx APIs work. If you are not careful, Windows will try to execute the first matching file on the command line as it parses each space.

For this reason it always makes sense to use quotes when calling CreateProcess and ShellExecuteEx directly. We need to know (via the Help) if InstallShield's wrapper functions do this already.

All my calls to LaunchAppAndWait and LaunchApplication first fully quote the filename. Based on the previous description I should now stop doing this.

However, what about when using the LAAW_OPTION_USE_SHELLEXECUTE option? Do you also quote szProgram before defining the SHELLEXECUTEINFO structure? If not and we can't either because of the change directory issue, surely InstallShield need to clearly document that LaunchAppAndWait no longer works with the LAAW_OPTION_USE_SHELLEXECUTE option.
0 Kudos
Ketan_bhagwat
Level 3

I am using Installshield 2009

I am selecting the path from user, but in some cases, if the program path is "c:/=/abc/program.bat" the LaunchAppAndWait is not launching the bat file, but it is giving success return value,

LaunchAppAndWait("C:\\=\\launch.bat\","",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);

LaunchAppAndWait("C:\\abc=\\launch.bat\","",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);

in above cases are not working, but if I will take a path

LaunchAppAndWait("C:\\abc =\\launch.bat\","",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);

It is working fine if we take space between special characters, what does mean that??
0 Kudos