c++ - 如何运行需要提升并等待的子进程?

标签 c++ winapi uac shellexecute createprocess

Win 7/UAC 快把我逼疯了。

在我的 C++ 应用程序中,我需要在 Windows 7 上运行需要提升的可执行文件。我想关闭这个东西并等待它完成后再继续。最简单的方法是什么?

我通常通过 CreateProcess() 来做这种事情,但是对于需要提升的可执行文件它会失败。

我尝试使用 cmd.exe/c ... 通过 CreateProcess 运行,它可以运行,但会弹出一个丑陋的 cmd 终端窗口。

我读到 ShellExecute() 将允许提升,但在使用 ShellExecute() 时等待 exe 完成似乎并不容易。 像 system() 这样简单的东西会起作用吗?

非常感谢任何其他想法!

最佳答案

使用 ShellExecuteEx ,而不是 ShellExecute。该函数将为创建的进程提供一个句柄,您可以使用它来调用 WaitForSingleObject 在该句柄上阻塞,直到该进程终止。最后,只需调用 CloseHandle 在进程句柄上关闭它。

示例代码(为了清晰和简洁省略了大部分错误检查):

SHELLEXECUTEINFO shExInfo = {0};
shExInfo.cbSize = sizeof(shExInfo);
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExInfo.hwnd = 0;
shExInfo.lpVerb = _T("runas");                // Operation to perform
shExInfo.lpFile = _T("C:\\MyApp.exe");       // Application to start    
shExInfo.lpParameters = "";                  // Additional parameters
shExInfo.lpDirectory = 0;
shExInfo.nShow = SW_SHOW;
shExInfo.hInstApp = 0;  

if (ShellExecuteEx(&shExInfo))
{
    WaitForSingleObject(shExInfo.hProcess, INFINITE);
    CloseHandle(shExInfo.hProcess);
}

lpVerb 指定“runas”动词是导致 UAC 提升即将启动的应用程序的原因。这相当于将应用程序 list 中的权限级别设置为“requireAdministrator”。管理员和受限用户都需要提升 UAC。

但值得注意的是,除非绝对必要,否则您应该更喜欢将 list 添加到要启动的应用程序的“标准”方式,以指定其所需的执行级别。如果你走这条路,你只需将“open”作为 lpVerb 传递。示例 list 如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <dependency>
                <dependentAssembly>
                        <assemblyIdentity
                                type="win32"
                                name="Microsoft.Windows.Common-Controls"
                                version="6.0.0.0"
                                processorArchitecture="X86"
                                publicKeyToken="6595b64144ccf1df"
                                language="*"
                        />
                </dependentAssembly>
        </dependency>
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
                <security>
                        <requestedPrivileges>
                                <requestedExecutionLevel 
                                       level="requireAdministrator" 
                                       uiAccess="false"/>
                        </requestedPrivileges>
                </security>
        </trustInfo>
</assembly>

最后,确保应用程序中触发执行需要 UAC 提升的进程的任何元素是 marked accordingly .在用户界面中对此进行建模是您的工作; Windows 不会为您处理它。这是通过在入口点上显示盾牌图标来完成的;例如:

         UAC shield displayed on a button UAC shield displayed on a menu item

关于c++ - 如何运行需要提升并等待的子进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4893262/

相关文章:

windows - 对注册表的更改不生效

c# - 当用户无权复制文件时使用 UAC 提示

windows - list 在 mingw 应用程序中被忽略

c++ - 如何在C++中获取变量的类型

c++ - 有没有办法使用 visual studio 命令提示符进行调试?

windows - 工具栏中按钮的大小 - win32 程序

c++ - 获取 FILE * 句柄而不实际在磁盘上创建文件

.net - 如何获得受信任/经过验证的发布者?

c++ - 包含算法会导致构建失败

c++ - 多态指针的typeid?