From 2d981bc1108572152a220e9ffaf56eb706534657 Mon Sep 17 00:00:00 2001 From: micio Date: Sat, 22 Jan 2011 17:36:20 +0000 Subject: [PATCH] Bazaar/SysExec : wait for executed process to finish on SysExecAdmin() git-svn-id: svn://ultimatepp.org/upp/trunk@3060 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/SysExec/ShellLib.cpp | 147 ++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/bazaar/SysExec/ShellLib.cpp b/bazaar/SysExec/ShellLib.cpp index 5470a72af..a67779ebb 100644 --- a/bazaar/SysExec/ShellLib.cpp +++ b/bazaar/SysExec/ShellLib.cpp @@ -1,72 +1,75 @@ -#include "ShellLib.h" -#include "ArgEnv.h" - -#ifdef PLATFORM_WIN32 - -#include - -NAMESPACE_UPP - -// executes a command via shell "runas" as admin user; -// if wait is true, will wait for command end, otherwise executes it in background -bool ShellExec(String const &args, VectorMap const &env, bool wait) -{ - // we use ShellExecuteEx to start an Admin process - - // as ShellExecuteEx doesn't take an environment argument, but inherits - // calling process one, we have to modify directly the environment before calling - - // copy original environment, for that we can use upp :-) - // don't know if Environment() funcitons returns a cached one, so - // to be sure we copy it - VectorMap prevEnv(Environment(), 1); - - // wipe original environment with windows api - for(int i = 0; i < prevEnv.GetCount(); i++) - SetEnvironmentVariable(prevEnv.GetKey(i), NULL); - - // insert new environment variables - for(int i = 0; i < env.GetCount(); i++) - SetEnvironmentVariable(env.GetKey(i), env[i]); - - // now we can use ShellExecute to raise process level - SHELLEXECUTEINFO info = - { - sizeof(SHELLEXECUTEINFO), // cbsize - SEE_MASK_NOASYNC, // fMask - 0, // hwnd - "runas", // lpVerb - args, // lpFile - 0, // lpParameters - 0, // lpDirectory - SW_SHOW, // nShow - 0, // hHinstApp -- result handle or error code - /* REST AS DEFAULT -- NOT NEEDED - LPVOID lpIDList; - LPCTSTR lpClass; - HKEY hkeyClass; - DWORD dwHotKey; - union { HANDLE hIcon; HANDLE hMonitor; } DUMMYUNIONNAME; - HANDLE hProcess; - */ - }; - - // if we shall wait for process termination, we shall get spawned process - // hanlde too... - if(wait) - info.fMask |= SEE_MASK_NOCLOSEPROCESS; - - bool res = ShellExecuteEx(&info); - - // restore the environment - for(int i = 0; i < prevEnv.GetCount(); i++) - SetEnvironmentVariable(env.GetKey(i), NULL); - for(int i = 0; i < env.GetCount(); i++) - SetEnvironmentVariable(prevEnv.GetKey(i), prevEnv[i]); - - return res; -} - -END_UPP_NAMESPACE - -#endif +#include "ShellLib.h" +#include "ArgEnv.h" + +#ifdef PLATFORM_WIN32 + +#include + +NAMESPACE_UPP + +// executes a command via shell "runas" as admin user; +// if wait is true, will wait for command end, otherwise executes it in background +bool ShellExec(String const &args, VectorMap const &env, bool wait) +{ + // we use ShellExecuteEx to start an Admin process + + // as ShellExecuteEx doesn't take an environment argument, but inherits + // calling process one, we have to modify directly the environment before calling + + // copy original environment, for that we can use upp :-) + // don't know if Environment() funcitons returns a cached one, so + // to be sure we copy it + VectorMap prevEnv(Environment(), 1); + + // wipe original environment with windows api + for(int i = 0; i < prevEnv.GetCount(); i++) + SetEnvironmentVariable(prevEnv.GetKey(i), NULL); + + // insert new environment variables + for(int i = 0; i < env.GetCount(); i++) + SetEnvironmentVariable(env.GetKey(i), env[i]); + + // now we can use ShellExecute to raise process level + SHELLEXECUTEINFO info = + { + sizeof(SHELLEXECUTEINFO), // cbsize + SEE_MASK_NOASYNC, // fMask + 0, // hwnd + "runas", // lpVerb + args, // lpFile + 0, // lpParameters + 0, // lpDirectory + SW_SHOW, // nShow + 0, // hHinstApp -- result handle or error code + /* REST AS DEFAULT -- NOT NEEDED + LPVOID lpIDList; + LPCTSTR lpClass; + HKEY hkeyClass; + DWORD dwHotKey; + union { HANDLE hIcon; HANDLE hMonitor; } DUMMYUNIONNAME; + HANDLE hProcess; + */ + }; + + // if we shall wait for process termination, we shall get spawned process + // hanlde too... + if(wait) + info.fMask |= SEE_MASK_NOCLOSEPROCESS; + + bool res = ShellExecuteEx(&info); + + // restore the environment + for(int i = 0; i < prevEnv.GetCount(); i++) + SetEnvironmentVariable(env.GetKey(i), NULL); + for(int i = 0; i < env.GetCount(); i++) + SetEnvironmentVariable(prevEnv.GetKey(i), prevEnv[i]); + + if(wait && res) + WaitForSingleObject(info.hProcess, INFINITE); + + return res; +} + +END_UPP_NAMESPACE + +#endif