Fix child updater processes receiving the wrong install directory on Windows of the path of the install directory contains spaces.

* Use the same argument quoting logic when launching both elevated
   and non-elevated processes under Windows
 * Include the executable name in the command-line when launching
   a non-elevated process.  Previously the child updater.exe process
   was receiving the '--install-dir' option name in argv[0] and ignoring
   it because it was only looking in argv[1..N-1]
 * Change the install path in the updater test to include a space.

TEST: Ran test-update.rb with space in test install directory
      under elevated/non-elevated cases.
This commit is contained in:
Robert Knight 2011-09-13 15:49:39 +01:00
parent c9c19fad3b
commit 724e91b216
2 changed files with 33 additions and 24 deletions

View file

@ -268,28 +268,37 @@ int ProcessUtils::runElevatedMac(const std::string& executable,
}
#endif
#ifdef PLATFORM_WINDOWS
int ProcessUtils::runElevatedWindows(const std::string& executable,
const std::list<std::string>& arguments)
// convert a list of arguments in a space-separated string.
// Arguments containing spaces are enclosed in quotes
std::string quoteArgs(const std::list<std::string>& arguments)
{
std::string args;
// quote process arguments
std::string quotedArgs;
for (std::list<std::string>::const_iterator iter = arguments.begin();
iter != arguments.end();
iter++)
{
std::string arg = *iter;
if (!arg.empty() && arg.at(0) != '"' && arg.at(arg.size()-1) != '"')
{
bool isQuoted = !arg.empty() &&
arg.at(0) == '"' &&
arg.at(arg.size()-1) == '"';
if (!isQuoted && arg.find(' ') != std::string::npos)
{
arg.insert(0,"\"");
arg.append("\"");
}
}
quotedArgs += arg;
quotedArgs += " ";
}
return quotedArgs;
}
args += arg;
args += " ";
}
#ifdef PLATFORM_WINDOWS
int ProcessUtils::runElevatedWindows(const std::string& executable,
const std::list<std::string>& arguments)
{
std::string args = quoteArgs(arguments);
SHELLEXECUTEINFO executeInfo;
ZeroMemory(&executeInfo,sizeof(executeInfo));
@ -350,18 +359,12 @@ PLATFORM_PID ProcessUtils::runAsyncUnix(const std::string& executable,
#ifdef PLATFORM_WINDOWS
int ProcessUtils::runWindows(const std::string& executable,
const std::list<std::string>& args,
const std::list<std::string>& _args,
RunMode runMode)
{
std::string commandLine = executable;
for (std::list<std::string>::const_iterator iter = args.begin(); iter != args.end(); iter++)
{
if (!commandLine.empty())
{
commandLine.append(" ");
}
commandLine.append(*iter);
}
std::list<std::string> args(_args);
args.push_front(executable);
std::string commandLine = quoteArgs(args);
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo,sizeof(startupInfo));

View file

@ -3,7 +3,10 @@
require 'fileutils.rb'
require 'rbconfig'
INSTALL_DIR = File.expand_path("install-dir/")
# Install directory - this contains a space to check
# for correct escaping of paths when passing comamnd
# line arguments under Windows
INSTALL_DIR = File.expand_path("install dir/")
PACKAGE_DIR = File.expand_path("package-dir/")
if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/)
@ -86,8 +89,11 @@ FileUtils.cp("../#{UPDATER_NAME}","#{PACKAGE_DIR}/#{UPDATER_NAME}")
# make sure that it looks in the correct directory for
# the file_list.xml file and packages
#
install_path = File.absolute_path(INSTALL_DIR)
Dir.chdir(INSTALL_DIR) do
system("#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir #{INSTALL_DIR} --package-dir #{PACKAGE_DIR} --script file_list.xml")
cmd = "#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir \"#{install_path}\" --package-dir \"#{PACKAGE_DIR}\" --script file_list.xml"
puts "Running '#{cmd}'"
system(cmd)
end
# TODO - Correctly wait until updater has finished