mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2025-01-22 15:31:08 +00:00
When re-launching the application after an update is installed, do it from a non-elevated process.
Previously the application was restarted from the main install process, which may have been elevated. The main application must be started from a non-elevated updater/updater.exe process otherwise the main app will inherit the elevated status from its parent. * Modify ProcessUtils::runElevated() to return the status code of the process * Change UpdateInstaller to run the main installation synchronously from the initial updater process in the case where elevation is not required. * Remove calls in main.cpp to relaunch the main application after the UI is closed.
This commit is contained in:
parent
d705095fe9
commit
098c9cb194
4 changed files with 63 additions and 30 deletions
|
@ -71,15 +71,15 @@ void ProcessUtils::runAsync(const std::string& executable,
|
|||
#endif
|
||||
}
|
||||
|
||||
void ProcessUtils::runElevated(const std::string& executable,
|
||||
int ProcessUtils::runElevated(const std::string& executable,
|
||||
const std::list<std::string>& args)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
runElevatedWindows(executable,args);
|
||||
return runElevatedWindows(executable,args);
|
||||
#elif defined(PLATFORM_MAC)
|
||||
runElevatedMac(executable,args);
|
||||
return runElevatedMac(executable,args);
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
runElevatedLinux(executable,args);
|
||||
return runElevatedLinux(executable,args);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ bool ProcessUtils::waitForProcess(PLATFORM_PID pid)
|
|||
}
|
||||
|
||||
#ifdef PLATFORM_LINUX
|
||||
void ProcessUtils::runElevatedLinux(const std::string& executable,
|
||||
int ProcessUtils::runElevatedLinux(const std::string& executable,
|
||||
const std::list<std::string>& args)
|
||||
{
|
||||
std::string sudoMessage = FileOps::fileName(executable.c_str()) + " needs administrative privileges. Please enter your password.";
|
||||
|
@ -152,9 +152,11 @@ void ProcessUtils::runElevatedLinux(const std::string& executable,
|
|||
int result = ProcessUtils::runSync(sudoBinary,sudoArgs);
|
||||
if (result != 255)
|
||||
{
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return RUN_ELEVATED_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -245,10 +247,13 @@ void ProcessUtils::runElevatedMac(const std::string& executable,
|
|||
{
|
||||
LOG(Info,"elevated process succeded with pid " + intToStr(childPid));
|
||||
}
|
||||
|
||||
return childStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Error,"failed to launch elevated process " + intToStr(status));
|
||||
return RUN_ELEVATED_FAILED;
|
||||
}
|
||||
|
||||
// If we want to know more information about what has happened:
|
||||
|
@ -262,13 +267,18 @@ void ProcessUtils::runElevatedMac(const std::string& executable,
|
|||
else
|
||||
{
|
||||
LOG(Error,"failed to get rights to launch elevated process. status: " + intToStr(status));
|
||||
return RUN_ELEVATED_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return RUN_ELEVATED_FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
void ProcessUtils::runElevatedWindows(const std::string& executable,
|
||||
int ProcessUtils::runElevatedWindows(const std::string& executable,
|
||||
const std::list<std::string>& arguments)
|
||||
{
|
||||
std::string args;
|
||||
|
@ -304,10 +314,14 @@ void ProcessUtils::runElevatedWindows(const std::string& executable,
|
|||
if (!ShellExecuteEx(&executeInfo))
|
||||
{
|
||||
LOG(Error,"Failed to start with admin priviledges using ShellExecuteEx()");
|
||||
return;
|
||||
return RUN_ELEVATED_FAILED;
|
||||
}
|
||||
|
||||
WaitForSingleObject(executeInfo.hProcess, INFINITE);
|
||||
|
||||
// this assumes the process succeeded - we need to check whether
|
||||
// this is actually the case.
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
class ProcessUtils
|
||||
{
|
||||
public:
|
||||
enum Errors
|
||||
{
|
||||
/** Status code returned by runElevated() if launching
|
||||
* the elevated process fails.
|
||||
*/
|
||||
RUN_ELEVATED_FAILED = 255
|
||||
};
|
||||
|
||||
static PLATFORM_PID currentProcessId();
|
||||
|
||||
static std::string currentProcessPath();
|
||||
|
@ -18,7 +26,13 @@ class ProcessUtils
|
|||
static void runAsync(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
static void runElevated(const std::string& executable,
|
||||
/** Run a process with administrative privileges and return the
|
||||
* status code of the process, or 0 on Windows.
|
||||
*
|
||||
* Returns RUN_ELEVATED_FAILED if the elevated process could
|
||||
* not be started.
|
||||
*/
|
||||
static int runElevated(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
static bool waitForProcess(PLATFORM_PID pid);
|
||||
|
@ -32,11 +46,11 @@ class ProcessUtils
|
|||
#endif
|
||||
|
||||
private:
|
||||
static void runElevatedLinux(const std::string& executable,
|
||||
static int runElevatedLinux(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
static void runElevatedMac(const std::string& executable,
|
||||
static int runElevatedMac(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
static void runElevatedWindows(const std::string& executable,
|
||||
static int runElevatedWindows(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
static PLATFORM_PID runAsyncUnix(const std::string& executable,
|
||||
|
|
|
@ -98,20 +98,40 @@ void UpdateInstaller::run() throw ()
|
|||
args.push_back("--wait");
|
||||
args.push_back(intToStr(ProcessUtils::currentProcessId()));
|
||||
|
||||
int installStatus = 0;
|
||||
if (!checkAccess())
|
||||
{
|
||||
LOG(Info,"Insufficient rights to install app to " + m_installDir + " requesting elevation");
|
||||
|
||||
// start a copy of the updater with admin rights
|
||||
ProcessUtils::runElevated(updaterPath,args);
|
||||
installStatus = ProcessUtils::runElevated(updaterPath,args);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Info,"Sufficient rights to install app - restarting with same permissions");
|
||||
|
||||
// TODO - Change this to run synchronously
|
||||
ProcessUtils::runAsync(updaterPath,args);
|
||||
installStatus = ProcessUtils::runSync(updaterPath,args);
|
||||
}
|
||||
|
||||
if (installStatus == 0)
|
||||
{
|
||||
LOG(Info,"Update install completed");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Error,"Update install failed with status " + intToStr(installStatus));
|
||||
}
|
||||
|
||||
// restart the main application - this is currently done
|
||||
// regardless of whether the installation succeeds or not
|
||||
restartMainApp();
|
||||
|
||||
// clean up files created by the updater
|
||||
std::list<std::string> cleanupArgs = updaterArgs();
|
||||
cleanupArgs.push_back("--mode");
|
||||
cleanupArgs.push_back("cleanup");
|
||||
cleanupArgs.push_back("--wait");
|
||||
cleanupArgs.push_back(intToStr(ProcessUtils::currentProcessId()));
|
||||
ProcessUtils::runAsync(updaterPath,cleanupArgs);
|
||||
}
|
||||
else if (m_mode == Main)
|
||||
{
|
||||
|
@ -152,13 +172,6 @@ void UpdateInstaller::run() throw ()
|
|||
{
|
||||
m_observer->updateFinished();
|
||||
}
|
||||
|
||||
std::list<std::string> args = updaterArgs();
|
||||
args.push_back("--mode");
|
||||
args.push_back("cleanup");
|
||||
args.push_back("--wait");
|
||||
args.push_back(intToStr(ProcessUtils::currentProcessId()));
|
||||
ProcessUtils::runAsync(updaterPath,args);
|
||||
}
|
||||
else if (m_mode == Cleanup)
|
||||
{
|
||||
|
|
|
@ -94,15 +94,9 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
|||
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||
dialog.exec();
|
||||
updaterThread.join();
|
||||
|
||||
if (dialog.restartApp())
|
||||
{
|
||||
installer->restartMainApp();
|
||||
}
|
||||
#else
|
||||
// no UI available - do a silent install
|
||||
installer->run();
|
||||
installer->restartMainApp();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -116,7 +110,6 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
|||
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||
dialog.exec();
|
||||
updaterThread.join();
|
||||
installer->restartMainApp();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -141,6 +134,5 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
|||
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||
dialog.exec();
|
||||
updaterThread.join();
|
||||
installer->restartMainApp();
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue