3

我通过 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)。

谢谢

4

3 回答 3

2

即使使用.FAR ManagerShellExecuteEx也能够检测到 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

您可以在源代码中查看他们所做的全部魔术。

于 2014-07-02T19:57:52.653 回答
2

如果ShellExecuteEx()没有返回错误,那么您无法检测到ShellExecuteEx's不受控制的 UAC 取消。

你应该做的是使用CreateProcess()。如果 UAC 拒绝新进程,这将返回错误。不要ShellExecuteEx()用于启动 .exe 文件,除非您使用“runas”动词来强制 UAC 提示。

于 2011-10-18T04:18:45.980 回答
0

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

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

于 2011-10-19T06:54:39.680 回答