当目标应用程序以管理员身份运行时,ShowWindow函数无法正常工作

7
我正在编写一个程序,用于显示/隐藏某个目标应用程序的窗口。早些时候我在测试它时发现了一些奇怪的问题。如果我以管理员身份运行目标应用程序(右键单击->属性,“兼容性”选项卡,“以管理员身份运行此程序”),它无法正常工作。
为了展示这个问题,我编写了一个简单的GUI应用程序称为“TargetApplication”,然后编写了以下代码来测试显示/隐藏此应用程序:
class Program
{
  static void Main(string[] args)
  {
    IntPtr windowPtr = FindWindow(null, "TargetApplication");
    ShowWindow(windowPtr, 0); // 0 = Hide            
    Console.WriteLine("The window is now hidden. Press Enter to restore");
    Console.ReadLine();
    ShowWindow(windowPtr, 9); // 9 = Restore
    Console.WriteLine("The window is now restored. Press Enter to exit.");            
    Console.ReadLine();
  }

  [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
  static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  [DllImport("user32.dll")]
  static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
}

如果我以非管理员身份启动窗口应用程序,则无法正常工作。

可以有人帮我测试一下吗?我已经上传了两个应用程序的.exe文件:

TestShowWindow 下载

您只需下载并运行TestApplication.exe,然后运行TestShowWindow.exe。您会发现将TestApplication.exe更改为以管理员身份运行会导致ShowWindow不再起作用。

当然,如果您不信任下载我的东西,您始终可以编译我的代码并在Windows中更改兼容性模式以在任何目标应用程序上进行测试。

顺便说一句,我不确定这是否有区别,但我正在运行Windows 8 Pro.64位。

2个回答

9
这是有意为之的。它是UAC的较少人知道的孪生兄弟,称为用户界面特权隔离(UIPI)。非提升程序无法夺取提升程序的控制权。考虑到UI自动化的能力,这是明显的反制措施,以防止程序劫持提升进程的功能。这种安全漏洞称为shatter攻击
解决方法是为存储在c:\windows或c:\program files中并提供证书的程序提供具有uiAccess = true的清单。对于目标程序来说,调用ChangeWindowMessageFilter以允许发送某些消息。在您的情况下,应该是WM_SHOWWINDOW。

哇,非常好的信息。唯一我不明白的是我有另一个程序,它可以执行相同的操作,并且可以正常工作。是否有其他方法可用于显示/隐藏窗口而不需要这个解决方法? - Jan Tacci

1
如果您不介意窗口表现得像您将其最小化到任务栏一样; 通常,您可以通过发送带有wParam为SC_RESTORE或SC_MINIMIZE的WM_SYSCOMMAND来显示和隐藏来自提升进程的窗口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接