如何以编程方式将UAC的consent.exe带到前台?

如何(如果可能的话)将Vista / Win7 UAC同意对话框置于前台,当它在任务栏中最小化时?

例如,请考虑以下情形:
我的应用程序在启动期间检查更新,它下载新的更新文件,并在我的应用程序关闭之后通过在Process.StartInfo中提供管理员密码来执行它。

此时,如果用户或Windows本身设法从MSI安装程序窗口失去焦点(可能通过单击桌面或其他窗口),UAC会看到安装程序窗口不是前台窗口,因此会弹出一个闪烁的同意对话框进入任务栏。

一些不那么明亮的客户不明白我的应用程序尚未完成更新并尝试重新启动应用程序。 在这个阶段,我可以枚举正在运行的进程,并找到任务栏中闪烁的consent.exe。

问题是我无法把它带到前台。 我试图用user32.dll用不同的参数(恢复,显示,正常)调用ShowWindow(),但没有任何反应。 我确实检查了MainWindowHandle进程,看起来没问题(它不是零或负数)。 我猜测问题在于UAC为同意对话框(安全桌面)创建了不同的桌面会话。

如果用户可以单击任务栏中的闪烁图标以将同意对话框带到前台,那么还应该可以通过代码模拟这个吗?

PS! 我正在使用C#

你尝试过SetForegroundWindow吗? 此外,在本机win32中没有任何称为主窗口,一个进程可以有0或任何数量的“主窗口”,但在consent.exe的情况下,我猜它只有一个…

编辑:

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { char buf[50]; *buf=0; GetClassName(hwnd,buf,50); buf[sizeof("$$$Secure UAP")-1]=0; if (!lstrcmp("$$$Secure UAP",buf)) { SwitchToThisWindow(hwnd,true); } return true; } ... EnumWindows(EnumWindowsProc,0); 

这将切换到安全桌面,但我不建议使用此,因为:

  • 它使用未记录的$$$ Secure UAP …窗口类
  • 使用SwitchToThisWindow是邪恶的,你不应该在用户不想要时切换焦点
  • 如果多个UAC确认对话框处于活动状态,则无法确定要切换到哪个consent.exe

问题是同意窗口不是拥有的弹出窗口,如果是,你可以确定你得到了正确的HWND。 希望Win8将获得同意,作为一个拥有弹出窗口,甚至更好的模式对话框。

这里有一个讨论可以帮助您: 如何最大化用户帐户控制(UAC)窗口?

有关该主题的官方文档如下: UAC兼容性(UAC)的重新设计