我通过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)。
由于
答案 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在两种情况下都会成功。问题是如何检测何时取消?
可能无法检测升级启动是成功还是失败是安全功能。否则,您可以探测系统以查找您不应该了解的已安装软件。