mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-25 14:22:54 -06:00
Bazaar/SysExec : wait for executed process to finish on SysExecAdmin()
git-svn-id: svn://ultimatepp.org/upp/trunk@3060 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fde39c3d75
commit
2d981bc110
1 changed files with 75 additions and 72 deletions
|
|
@ -1,72 +1,75 @@
|
|||
#include "ShellLib.h"
|
||||
#include "ArgEnv.h"
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#include <Shellapi.h>
|
||||
|
||||
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<String, String> 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<String, String> 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 <Shellapi.h>
|
||||
|
||||
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<String, String> 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<String, String> 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue