This is another issue we've found when investigating problem described in post http://www.advancedinstaller.com/forums ... php?t=4986.
This time the problem is that bootstrapper doesn't work when all of the following conditions are met:
- the installer is invoked by another application which passes short (MS-DOS) path to the installer (.exe) when calling CreateProcess
- the installer is called from a directory which has wide characters in its path.
- Create a default Enterprise project with AI 6.1 (in my case project language was set to English(UK))
- Configure it to add any file to Application Directory
- In Media->Media select Archive installation files into CAB files
- Make sure that in Bootstrapper tab Create EXE setup file and Include install files in EXE are selected.
- build project
- put the installer to directory which has wide characters in the path (I've tried it on a Japanese Windows XP; I've put the installer onto Desktop of user イル)
- run the following application passing it S as first parameter and full, long path to the installer as second parameter:
Code: Select all
#include <TCHAR.h> #include <windows.h> #include <vector> #include <iostream> #include <string> int wmain(int argc, wchar_t* argv[]) { if ( 3 != argc ) { std::cerr << "Parameters: " << std::endl; std::cerr << " L | S - first parameter (case sensitive) saying whether CreateProcess should be called with Short od Long Path" << std::endl; std::cerr << " <path> - second parameter should be full path to the installer" << std::endl; return -1; } STARTUPINFOW startupInfo = {0}; startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInformation = {0}; if ( L'S' == argv[1][0] ) { std::vector<wchar_t> shortInstallerPath( 1, L'\0' ); // set size to 1 to allow &shortInstallerPath[0] call const DWORD shortInstallerPathLength = GetShortPathNameW( argv[2], &shortInstallerPath[0], (DWORD) shortInstallerPath.size() ); if ( shortInstallerPathLength > shortInstallerPath.size() ) { shortInstallerPath.resize( shortInstallerPathLength + 1, L'\0' ); // + 1 to allow for terminating NULL char } if ( GetShortPathNameW( argv[2], &shortInstallerPath[0], (DWORD) shortInstallerPath.size() ) != 0 ) { std::cout << "Calling CreateProcess with short path" << std::endl; if ( CreateProcessW(NULL, &shortInstallerPath[0], NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation ) == 0 ) { std::cerr << "CreateProcess failed with error code: " << GetLastError() << std::endl; return -1; } } else { std::cerr << "GetShortPathName failed with error code: " << GetLastError() << std::endl; return -1; } } else if ( L'L' == argv[1][0] ) { std::cout << "Calling CreateProcess with long path" << std::endl; if ( CreateProcessW(NULL, argv[2], NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation ) == 0 ) { std::cerr << "CreateProcess failed with error code: " << GetLastError() << std::endl; return -1; } } else { std::cerr << "Incorrect first parameter." << std::endl; } return 0; }
- Instead of installation you'll see msiexec help dialog box
This problem can be easily worked around by using long paths (use the app shown with L as first parameter). I'm raising this problem as it may be symptom of more dangerous bug.
Would you be so kind as to confirm that using long paths is good enough workaround for this problem.
Thank you so much,
Rafal