Merge with develop
--HG-- branch : feature-ryzom-installer
This commit is contained in:
commit
6e301d59cd
4 changed files with 213 additions and 62 deletions
|
@ -366,6 +366,9 @@ std::string formatThousands(const std::string& s);
|
||||||
/// The program will be launched in the current directory
|
/// The program will be launched in the current directory
|
||||||
bool launchProgram (const std::string &programName, const std::string &arguments, bool log = true);
|
bool launchProgram (const std::string &programName, const std::string &arguments, bool log = true);
|
||||||
|
|
||||||
|
/// Same but with an array of strings for arguments
|
||||||
|
bool launchProgramArray (const std::string &programName, const std::vector<std::string> &arguments, bool log = true);
|
||||||
|
|
||||||
/// This function executes a program and wait for result (used for example for crash report).
|
/// This function executes a program and wait for result (used for example for crash report).
|
||||||
/// The program will be launched in the current directory
|
/// The program will be launched in the current directory
|
||||||
sint launchProgramAndWaitForResult (const std::string &programName, const std::string &arguments, bool log = true);
|
sint launchProgramAndWaitForResult (const std::string &programName, const std::string &arguments, bool log = true);
|
||||||
|
@ -378,6 +381,10 @@ std::string getCommandOutput(const std::string &command);
|
||||||
/// Authorized characters in names are A-Z, a-z, 0-9 and _
|
/// Authorized characters in names are A-Z, a-z, 0-9 and _
|
||||||
std::string expandEnvironmentVariables(const std::string &s);
|
std::string expandEnvironmentVariables(const std::string &s);
|
||||||
|
|
||||||
|
/// Functions to convert a string with arguments to array or array to string (will espace strings with spaces)
|
||||||
|
bool explodeArguments(const std::string &str, std::vector<std::string> &args);
|
||||||
|
std::string joinArguments(const std::vector<std::string> &args);
|
||||||
|
|
||||||
/// This function kills a program using his pid (on unix, it uses the kill() POSIX function)
|
/// This function kills a program using his pid (on unix, it uses the kill() POSIX function)
|
||||||
bool killProgram(uint32 pid);
|
bool killProgram(uint32 pid);
|
||||||
|
|
||||||
|
|
|
@ -202,42 +202,13 @@ bool CCmdArgs::parse(const std::string &args)
|
||||||
wchar_t str[4096];
|
wchar_t str[4096];
|
||||||
uint len = GetModuleFileNameW(NULL, str, 4096);
|
uint len = GetModuleFileNameW(NULL, str, 4096);
|
||||||
|
|
||||||
|
// first argument should be full path to executable
|
||||||
if (len && len < 4096)
|
if (len && len < 4096)
|
||||||
argv.push_back(wideToUtf8(str));
|
argv.push_back(wideToUtf8(str));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string::size_type pos1 = 0, pos2 = 0;
|
// convert string with arguments to array
|
||||||
|
explodeArguments(args, argv);
|
||||||
do
|
|
||||||
{
|
|
||||||
// Look for the first non space character
|
|
||||||
pos1 = args.find_first_not_of (" ", pos2);
|
|
||||||
if(pos1 == std::string::npos) break;
|
|
||||||
|
|
||||||
// Look for the first space or "
|
|
||||||
pos2 = args.find_first_of (" \"", pos1);
|
|
||||||
if(pos2 != std::string::npos)
|
|
||||||
{
|
|
||||||
// " ?
|
|
||||||
if(args[pos2] == '"')
|
|
||||||
{
|
|
||||||
// Look for the final \"
|
|
||||||
pos2 = args.find_first_of ("\"", pos2+1);
|
|
||||||
if(pos2 != std::string::npos)
|
|
||||||
{
|
|
||||||
// Look for the first space
|
|
||||||
pos2 = args.find_first_of (" ", pos2+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the size of the string to extract
|
|
||||||
std::string::difference_type length = (pos2 != std::string::npos) ? pos2-pos1 : std::string::npos;
|
|
||||||
|
|
||||||
std::string tmp = args.substr (pos1, length);
|
|
||||||
argv.push_back (tmp);
|
|
||||||
}
|
|
||||||
while(pos2 != std::string::npos);
|
|
||||||
|
|
||||||
return parse(argv);
|
return parse(argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -831,6 +831,7 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool firstLaunchProgram = true;
|
static bool firstLaunchProgram = true;
|
||||||
|
|
||||||
if (firstLaunchProgram)
|
if (firstLaunchProgram)
|
||||||
{
|
{
|
||||||
// The aim of this is to avoid defunct process.
|
// The aim of this is to avoid defunct process.
|
||||||
|
@ -851,15 +852,7 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
||||||
|
|
||||||
// convert one arg into several args
|
// convert one arg into several args
|
||||||
vector<string> args;
|
vector<string> args;
|
||||||
string::size_type pos1 = 0, pos2 = 0;
|
explodeArguments(arguments, args);
|
||||||
do
|
|
||||||
{
|
|
||||||
pos1 = arguments.find_first_not_of (" ", pos2);
|
|
||||||
if (pos1 == string::npos) break;
|
|
||||||
pos2 = arguments.find_first_of (" ", pos1);
|
|
||||||
args.push_back (arguments.substr (pos1, pos2-pos1));
|
|
||||||
}
|
|
||||||
while (pos2 != string::npos);
|
|
||||||
|
|
||||||
// Store the size of each arg
|
// Store the size of each arg
|
||||||
vector<char *> argv(args.size()+2);
|
vector<char *> argv(args.size()+2);
|
||||||
|
@ -904,6 +897,110 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool launchProgramArray (const std::string &programName, const std::vector<std::string> &arguments, bool log)
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
|
std::string argumentsJoined = joinArguments(arguments);
|
||||||
|
|
||||||
|
if (!createProcess(programName, argumentsJoined, log, pi)) return false;
|
||||||
|
|
||||||
|
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
|
||||||
|
CloseHandle( pi.hProcess );
|
||||||
|
CloseHandle( pi.hThread );
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef NL_OS_MAC
|
||||||
|
// special OS X case with bundles
|
||||||
|
if (toLower(programName).find(".app") != std::string::npos)
|
||||||
|
{
|
||||||
|
// we need to open bundles with "open" command
|
||||||
|
std::string command = NLMISC::toString("open \"%s\"", programName.c_str());
|
||||||
|
|
||||||
|
// append arguments if any
|
||||||
|
if (!arguments.empty())
|
||||||
|
{
|
||||||
|
command += NLMISC::toString(" --args %s", joinArguments(arguments).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = system(command.c_str());
|
||||||
|
|
||||||
|
if (!res) return true;
|
||||||
|
|
||||||
|
if (log)
|
||||||
|
{
|
||||||
|
nlwarning ("LAUNCH: Failed launched '%s' with arg '%s' return code %d", programName.c_str(), arguments.c_str(), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool firstLaunchProgram = true;
|
||||||
|
|
||||||
|
if (firstLaunchProgram)
|
||||||
|
{
|
||||||
|
// The aim of this is to avoid defunct process.
|
||||||
|
//
|
||||||
|
// From "man signal":
|
||||||
|
//------
|
||||||
|
// According to POSIX (3.3.1.3) it is unspecified what happens when SIGCHLD is set to SIG_IGN. Here
|
||||||
|
// the BSD and SYSV behaviours differ, causing BSD software that sets the action for SIGCHLD to
|
||||||
|
// SIG_IGN to fail on Linux.
|
||||||
|
//------
|
||||||
|
//
|
||||||
|
// But it works fine on my GNU/Linux so I do this because it's easier :) and I don't know exactly
|
||||||
|
// what to do to be portable.
|
||||||
|
signal(SIGCHLD, SIG_IGN);
|
||||||
|
|
||||||
|
firstLaunchProgram = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the size of each arg
|
||||||
|
vector<char *> argv(arguments.size()+2);
|
||||||
|
uint i = 0;
|
||||||
|
argv[i] = (char *)programName.c_str();
|
||||||
|
for (; i < arguments.size(); i++)
|
||||||
|
{
|
||||||
|
argv[i+1] = (char *) arguments[i].c_str();
|
||||||
|
}
|
||||||
|
argv[i+1] = NULL;
|
||||||
|
|
||||||
|
int status = vfork ();
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
/// WARNING : NO MORE INSTRUCTION AFTER VFORK !
|
||||||
|
/// READ VFORK manual
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
if (status == -1)
|
||||||
|
{
|
||||||
|
char *err = strerror (errno);
|
||||||
|
if (log)
|
||||||
|
nlwarning("LAUNCH: Failed launched '%s' with arg '%s' err %d: '%s'", programName.c_str(), arguments.c_str(), errno, err);
|
||||||
|
}
|
||||||
|
else if (status == 0)
|
||||||
|
{
|
||||||
|
// Exec (the only allowed instruction after vfork)
|
||||||
|
status = execvp(programName.c_str(), &argv.front());
|
||||||
|
|
||||||
|
if (status == -1)
|
||||||
|
{
|
||||||
|
perror("Failed launched");
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
sint launchProgramAndWaitForResult(const std::string &programName, const std::string &arguments, bool log)
|
sint launchProgramAndWaitForResult(const std::string &programName, const std::string &arguments, bool log)
|
||||||
{
|
{
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
@ -1039,6 +1136,75 @@ std::string expandEnvironmentVariables(const std::string &s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool explodeArguments(const std::string &str, std::vector<std::string> &args)
|
||||||
|
{
|
||||||
|
if (str.empty()) return false;
|
||||||
|
|
||||||
|
std::string::size_type pos1 = 0, pos2 = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Look for the first non space character
|
||||||
|
pos1 = str.find_first_not_of (" ", pos2);
|
||||||
|
if (pos1 == std::string::npos) break;
|
||||||
|
|
||||||
|
// Look for the first space or "
|
||||||
|
pos2 = str.find_first_of (" \"", pos1);
|
||||||
|
if (pos2 != std::string::npos)
|
||||||
|
{
|
||||||
|
// " ?
|
||||||
|
if (str[pos2] == '"')
|
||||||
|
{
|
||||||
|
// Look for the final \"
|
||||||
|
pos2 = str.find_first_of ("\"", pos2+1);
|
||||||
|
if (pos2 != std::string::npos)
|
||||||
|
{
|
||||||
|
// Look for the first space
|
||||||
|
pos2 = str.find_first_of (" ", pos2+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the size of the string to extract
|
||||||
|
std::string::difference_type length = (pos2 != std::string::npos) ? pos2-pos1 : std::string::npos;
|
||||||
|
|
||||||
|
std::string tmp = str.substr (pos1, length);
|
||||||
|
|
||||||
|
// remove escape " from argument
|
||||||
|
if (tmp.length() > 1 && tmp[0] == '"' && tmp[tmp.length()-1] == '"') tmp = tmp.substr(1, tmp.length()-2);
|
||||||
|
|
||||||
|
args.push_back (tmp);
|
||||||
|
}
|
||||||
|
while(pos2 != std::string::npos);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string joinArguments(const std::vector<std::string> &args)
|
||||||
|
{
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
for(uint i = 0, len = (uint)args.size(); i < len; ++i)
|
||||||
|
{
|
||||||
|
const std::string &arg = args[i];
|
||||||
|
|
||||||
|
// prepend space
|
||||||
|
if (!res.empty()) res += " ";
|
||||||
|
|
||||||
|
// escape only if spaces or empty argument
|
||||||
|
if (arg.empty() || arg.find(' ') != std::string::npos)
|
||||||
|
{
|
||||||
|
res += "\"" + arg + "\"";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res += arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display the bits (with 0 and 1) composing a byte (from right to left)
|
* Display the bits (with 0 and 1) composing a byte (from right to left)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -167,18 +167,18 @@ CPatchManager::CPatchManager() : State("t_state"), DataScanState("t_data_scan_st
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
||||||
#elif defined(NL_OS_WIN32)
|
#elif defined(NL_OS_WIN32)
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_win34");
|
ForceRemovePatchCategories.push_back("main_exedll_win64");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
||||||
#elif defined(NL_OS_APPLE)
|
#elif defined(NL_OS_APPLE)
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_win32");
|
ForceRemovePatchCategories.push_back("main_exedll_win32");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_win34");
|
ForceRemovePatchCategories.push_back("main_exedll_win64");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
ForceRemovePatchCategories.push_back("main_exedll_linux64");
|
||||||
#elif defined(NL_OS_UNIX) && defined(_LP64)
|
#elif defined(NL_OS_UNIX) && defined(_LP64)
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_win32");
|
ForceRemovePatchCategories.push_back("main_exedll_win32");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_win34");
|
ForceRemovePatchCategories.push_back("main_exedll_win64");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
ForceRemovePatchCategories.push_back("main_exedll_linux32");
|
||||||
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
ForceRemovePatchCategories.push_back("main_exedll_osx");
|
||||||
#else
|
#else
|
||||||
|
@ -826,8 +826,8 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
content += toString("move %s %s\n", realSrcPath.c_str(), realDstPath.c_str());
|
content += toString("move %s %s\n", realSrcPath.c_str(), realDstPath.c_str());
|
||||||
#else
|
#else
|
||||||
// use DSTPATH and SRCPATH variables and append filenames
|
// use DSTPATH and SRCPATH variables and append filenames
|
||||||
string realDstPath = toString("\"$ROOTPATH\\%s\"", batchRelativeDstPath.c_str());
|
string realDstPath = toString("\"$ROOTPATH/%s\"", batchRelativeDstPath.c_str());
|
||||||
string realSrcPath = toString("\"$UNPACKPATH\\%s\"", FileName.c_str());
|
string realSrcPath = toString("\"$UNPACKPATH/%s\"", FileName.c_str());
|
||||||
|
|
||||||
content += toString("rm -rf %s\n", realDstPath.c_str());
|
content += toString("rm -rf %s\n", realDstPath.c_str());
|
||||||
content += toString("mv %s %s\n", realSrcPath.c_str(), realDstPath.c_str());
|
content += toString("mv %s %s\n", realSrcPath.c_str(), realDstPath.c_str());
|
||||||
|
@ -916,19 +916,21 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
contentPrefix += "set RYZOM_CLIENT=\"%1\"\n";
|
contentPrefix += "set RYZOM_CLIENT=\"%1\"\n";
|
||||||
contentPrefix += "set UNPACKPATH=\"%2\"\n";
|
contentPrefix += "set UNPACKPATH=\"%2\"\n";
|
||||||
contentPrefix += "set ROOTPATH=\"%3\"\n";
|
contentPrefix += "set ROOTPATH=\"%3\"\n";
|
||||||
|
contentPrefix += toString("set UPGRADE_FILE=\"%%ROOTPATH%%\\%s\"\n", UpgradeBatchFilename.c_str());
|
||||||
|
contentPrefix += "\n";
|
||||||
contentPrefix += "set LOGIN=%4\n";
|
contentPrefix += "set LOGIN=%4\n";
|
||||||
contentPrefix += "set PASSWORD=%5\n";
|
contentPrefix += "set PASSWORD=%5\n";
|
||||||
contentPrefix += "set SHARDID=%6\n";
|
contentPrefix += "set SHARDID=%6\n";
|
||||||
contentPrefix += toString("set UPGRADE_FILE=\"%%ROOTPATH%%\\%s\"\n", UpgradeBatchFilename.c_str());
|
|
||||||
#else
|
#else
|
||||||
contentPrefix += "#!/bin/sh\n";
|
contentPrefix += "#!/bin/sh\n";
|
||||||
contentPrefix += "RYZOM_CLIENT=\"$1\"\n";
|
contentPrefix += "export RYZOM_CLIENT=$1\n";
|
||||||
contentPrefix += "UNPACKPATH=\"$2\"\n";
|
contentPrefix += "export UNPACKPATH=$2\n";
|
||||||
contentPrefix += "ROOTPATH=\"$3\"\n";
|
contentPrefix += "export ROOTPATH=$3\n";
|
||||||
|
contentPrefix += toString("export UPGRADE_FILE=$ROOTPATH/%s\n", UpgradeBatchFilename.c_str());
|
||||||
|
contentPrefix += "\n";
|
||||||
contentPrefix += "LOGIN=$4\n";
|
contentPrefix += "LOGIN=$4\n";
|
||||||
contentPrefix += "PASSWORD=$5\n";
|
contentPrefix += "PASSWORD=$5\n";
|
||||||
contentPrefix += "SHARDID=$6\n";
|
contentPrefix += "SHARDID=$6\n";
|
||||||
contentPrefix += toString("UPGRADE_FILE=\"$ROOTPATH\\%s\"\n", UpgradeBatchFilename.c_str());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
contentPrefix += "\n";
|
contentPrefix += "\n";
|
||||||
|
@ -960,15 +962,15 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// launch upgrade script if present (it'll execute additional steps like moving or deleting files)
|
// launch upgrade script if present (it'll execute additional steps like moving or deleting files)
|
||||||
contentSuffix += "if [ -e \"$UPGRADE_FILE\" ]; then chmod +x \"$UPGRADE_FILE\" && \"$UPGRADE_FILE\"; fi\n";
|
contentSuffix += "if [ -e \"$UPGRADE_FILE\" ]; then chmod +x \"$UPGRADE_FILE\" && \"$UPGRADE_FILE\"; fi\n\n";
|
||||||
|
|
||||||
// be sure file is executable
|
// be sure file is executable
|
||||||
contentSuffix += "chmod +x \"$RYZOM_CLIENT\"\n";
|
contentSuffix += "chmod +x \"$RYZOM_CLIENT\"\n\n";
|
||||||
|
|
||||||
if (wantRyzomRestart)
|
if (wantRyzomRestart)
|
||||||
{
|
{
|
||||||
// change to previous client directory
|
// change to previous client directory
|
||||||
contentSuffix += "cd \"$ROOTPATH\"\n";
|
contentSuffix += "cd \"$ROOTPATH\"\n\n";
|
||||||
|
|
||||||
// launch new client
|
// launch new client
|
||||||
contentSuffix += toString("\"$RYZOM_CLIENT\" %s $LOGIN $PASSWORD $SHARDID\n", additionalParams.c_str());
|
contentSuffix += toString("\"$RYZOM_CLIENT\" %s $LOGIN $PASSWORD $SHARDID\n", additionalParams.c_str());
|
||||||
|
@ -1020,32 +1022,37 @@ void CPatchManager::executeBatchFile()
|
||||||
// make script executable
|
// make script executable
|
||||||
CFile::setRWAccess(batchFilename);
|
CFile::setRWAccess(batchFilename);
|
||||||
|
|
||||||
std::string arguments;
|
std::vector<std::string> arguments;
|
||||||
|
|
||||||
// 3 first parameters are Ryzom client full path, patch directory full path and client root directory full path
|
// 3 first parameters are Ryzom client full path, patch directory full path and client root directory full path
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
arguments += "\"" + CPath::standardizeDosPath(RyzomFilename) + "\" \"" + CPath::standardizeDosPath(ClientPatchPath) + "\" \"" + CPath::standardizeDosPath(ClientRootPath) + "\"";
|
arguments.push_back(CPath::standardizeDosPath(RyzomFilename));
|
||||||
|
arguments.push_back(CPath::standardizeDosPath(ClientPatchPath));
|
||||||
|
arguments.push_back(CPath::standardizeDosPath(ClientRootPath));
|
||||||
#else
|
#else
|
||||||
arguments += "\"" + RyzomFilename + "\" \"" + ClientPatchPath + "\" " + ClientRootPath + "\"";
|
arguments.push_back(RyzomFilename);
|
||||||
|
arguments.push_back(ClientPatchPath);
|
||||||
|
arguments.push_back(ClientRootPath);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// append login, password and shard
|
// append login, password and shard
|
||||||
if (!LoginLogin.empty())
|
if (!LoginLogin.empty())
|
||||||
{
|
{
|
||||||
arguments += " " + LoginLogin;
|
arguments.push_back(LoginLogin);
|
||||||
|
|
||||||
if (!LoginPassword.empty())
|
if (!LoginPassword.empty())
|
||||||
{
|
{
|
||||||
arguments += " " + LoginPassword;
|
arguments.push_back(LoginPassword);
|
||||||
|
|
||||||
if (!r2Mode)
|
if (!r2Mode)
|
||||||
{
|
{
|
||||||
arguments += " " + toString(LoginShardId);
|
arguments.push_back(toString(LoginShardId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!launchProgram(batchFilename, arguments, false))
|
// launchProgram with array of strings as argument will escape arguments with spaces
|
||||||
|
if (!launchProgramArray(batchFilename, arguments, false))
|
||||||
{
|
{
|
||||||
// error occurs during the launch
|
// error occurs during the launch
|
||||||
string str = toString("Can't execute '%s': code=%d %s (error code 30)", batchFilename.c_str(), errno, strerror(errno));
|
string str = toString("Can't execute '%s': code=%d %s (error code 30)", batchFilename.c_str(), errno, strerror(errno));
|
||||||
|
|
Loading…
Reference in a new issue