如何检测是否由UAC取消了是否通过ShellExecuteEx启动

时间:2011-10-18 03:38:33

标签: c++ winapi uac shellexecuteex

我通过ShellExecuteEx启动exe:

tstring sPath = _T("C:\\Test\\MyApp.exe");
tstring sArgs = _T("/S");
SHELLEXECUTEINFO lpExecInfo = {0,};
lpExecInfo.cbSize  = sizeof(SHELLEXECUTEINFO);
lpExecInfo.lpFile = sPath.c_str();
lpExecInfo.fMask=SEE_MASK_NOASYNC ;     
lpExecInfo.hwnd = NULL;
lpExecInfo.lpVerb = NULL;
lpExecInfo.lpParameters = sArgs.c_str();
lpExecInfo.lpDirectory = NULL;
lpExecInfo.nShow = SW_SHOWNORMAL;

if (!ShellExecuteEx(&lpExecInfo)) {
    // handle the error
    throw CException("Cannot launch an application");
}

int nRes = (int)lpExecInfo.hInstApp; // nRes = 42
DWORD dwErr = GetLastError(); // dwErr = 0

如何检测UAC是否取消启动?在这种情况下,ShellExecuteEx成功(hInstApp = 42,GetLastError返回0)。

由于

3 个答案:

答案 0 :(得分:2)

如果ShellExecuteEx()没有返回错误,那么您无法检测到在ShellExecuteEx's控件之外发生的UAC取消。

您应该做的是使用CreateProcess()代替。如果UAC重新审视新进程,那将返回错误。不要使用ShellExecuteEx()启动.exe文件,除非您使用“runas”动词强制UAC提示。

答案 1 :(得分:2)

即使使用ShellExecuteEx

FAR Manager也可以检测到UAC取消。

   ╔════════════ Error ═════════════╗
   ║      Operation cancelled       ║
   ║         Cannot execute         ║
   ║ D:\Downloads\fiddler4setup.exe ║
   ║               OK               ║
   ╚════════════════════════════════╝

我已经检查过调试器下发生了什么,以及结构如何:

lpVerb = "open";
lpFile = <path to the .exe>;
lpParameters = "";
lpDirectory = <current directory>;
nShow = SW_SHOWNORMAL;
fMask = SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOASYNC|
   SEE_MASK_FLAG_NO_UI|SEE_MASK_NOZONECHECKS; // 0x800540

您可以在the source code中查看他们所做的全部魔术。

答案 2 :(得分:1)

  

现在的问题是,在取消启动并且未取消启动时,CreateProcess在两种情况下都会成功。问题是如何检测何时取消?

可能无法检测升级启动是成功还是失败是安全功能。否则,您可以探测系统以查找您不应该了解的已安装软件。