mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2024-11-10 06:31:49 +00:00
Fix failure to start application after install on Windows systems which do not have the required side-by-side libraries installed system-wide.
It appears that the previous fix was incorrect. The issue was not with the current directory used by the process but that the executable path passed to CreateProcess() used forward slashes instead of back slashes. A runtime error in loading the WinSxS DLLs (the C++ runtime library) resulted. Although most Windows API functions both back and forward slashes, this appears not to be the case for loading of side-by-side DLLs from the application's directory under Windows XP. This may be related to the LoadLibrary() function whose documentation specifies that backslashes must be used instead of forward slashes. This commit converts the executable path to use backslashes before passing it to CreateProcess() and removes the previous change to alter the current working directory before starting the main app binary.
This commit is contained in:
parent
61e8c92550
commit
3319c4ad3e
4 changed files with 27 additions and 20 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "Platform.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
|
@ -320,10 +321,12 @@ std::string FileUtils::dirname(const char* path)
|
|||
free(pathCopy);
|
||||
return dirname;
|
||||
#else
|
||||
char drive[3];
|
||||
char dir[MAX_PATH];
|
||||
|
||||
_splitpath_s(path,
|
||||
0, /* drive */
|
||||
0, /* drive length */
|
||||
drive, /* drive */
|
||||
3, /* drive length */
|
||||
dir,
|
||||
MAX_PATH, /* dir length */
|
||||
0, /* filename */
|
||||
|
@ -331,6 +334,7 @@ std::string FileUtils::dirname(const char* path)
|
|||
0, /* extension */
|
||||
0 /* extension length */
|
||||
);
|
||||
|
||||
return std::string(dir);
|
||||
#endif
|
||||
}
|
||||
|
@ -422,16 +426,17 @@ std::string FileUtils::canonicalPath(const char* path)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::string FileUtils::toWindowsPathSeparators(const std::string& str)
|
||||
{
|
||||
std::string result = str;
|
||||
std::replace(result.begin(),result.end(),'/','\\');
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string FileUtils::toUnixPathSeparators(const std::string& str)
|
||||
{
|
||||
std::string result = str;
|
||||
for (size_t i=0; i < result.size(); i++)
|
||||
{
|
||||
if (result[i] == '\\')
|
||||
{
|
||||
result[i] = '/';
|
||||
}
|
||||
}
|
||||
std::replace(result.begin(),result.end(),'\\','/');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ class FileUtils
|
|||
*/
|
||||
static std::string toUnixPathSeparators(const std::string& str);
|
||||
|
||||
static std::string toWindowsPathSeparators(const std::string& str);
|
||||
|
||||
/** Returns true if the provided path is relative.
|
||||
* Or false if absolute.
|
||||
*/
|
||||
|
|
|
@ -402,10 +402,20 @@ PLATFORM_PID ProcessUtils::runAsyncUnix(const std::string& executable,
|
|||
#endif
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
int ProcessUtils::runWindows(const std::string& executable,
|
||||
int ProcessUtils::runWindows(const std::string& _executable,
|
||||
const std::list<std::string>& _args,
|
||||
RunMode runMode)
|
||||
{
|
||||
// most Windows API functions allow back and forward slashes to be
|
||||
// used interchangeably. However, an application started with
|
||||
// CreateProcess() may fail to find Side-by-Side library dependencies
|
||||
// in the same directory as the executable if forward slashes are
|
||||
// used as path separators, so convert the path to use back slashes here.
|
||||
//
|
||||
// This may be related to LoadLibrary() requiring backslashes instead
|
||||
// of forward slashes.
|
||||
std::string executable = FileUtils::toWindowsPathSeparators(_executable);
|
||||
|
||||
std::list<std::string> args(_args);
|
||||
args.push_front(executable);
|
||||
std::string commandLine = quoteArgs(args);
|
||||
|
|
|
@ -420,17 +420,7 @@ void UpdateInstaller::restartMainApp()
|
|||
if (!command.empty())
|
||||
{
|
||||
LOG(Info,"Starting main application " + command);
|
||||
|
||||
// change the current directory to that of the application binary,
|
||||
// so that on Windows the application can find shared libraries
|
||||
// that it depends on which are in the same directory
|
||||
std::string appDir = FileUtils::dirname(command.c_str());
|
||||
std::string currentDir = FileUtils::getcwd();
|
||||
FileUtils::chdir(appDir.c_str());
|
||||
|
||||
ProcessUtils::runAsync(command,args);
|
||||
|
||||
FileUtils::chdir(currentDir.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue