当我拥有UIAccess权限时,为什么SetWindowPos无法将窗口置于z-order的前面? (Windows 7的)

时间:2013-03-15 10:15:08

标签: windows uac z-order uia

我遇到了SetWindowPos无法将外部进程的窗口可靠地置于z-order顶部的问题。我可以把窗户带到前面,如:

     NativeMethods.SetWindowPos(hwnd, new IntPtr(-1), Left, Top, Width, Height, 0x10);
     NativeMethods.SetWindowPos(hwnd, new IntPtr(-2), Left, Top, Width, Height, 0x10);

虽然它没有100%的工作时间。经过一番阅读,我找到了一些东西。

SetWindowPos文档说明:

    To use SetWindowPos to bring a window to the top, the process that owns the window must have SetForegroundWindow permission.

MSDN上的一篇文章然后陈述

    A process that is started with UIAccess rights has the following abilities:
    * Set the foreground window.

AllowSetForeground提及

    The calling process must already be able to set the foreground window

我已经签署了我的.exe并启用了UIAccess,以便我可以在清单中设置前景窗口:

     <requestedExecutionLevel  level="highestAvailable" uiAccess="true" />

我的程序启动,我得到UAC提示请求许可。然后我测试UIAccess,管理员权限和TokenElevationType。前2个返回true,第3个返回TokenElevationTypeFull。尽管如此,我仍然遇到了同样的问题。

我的代码是:

    uint processid=0;
    NativeMethods.GetWindowThreadProcessId(hwnd, out processid);
    NativeMethods.AllowSetForegroundWindow((int)processid);
    NativeMethods.SetWindowPos(hwnd, IntPtr.Zero, Left, Top, Width, Height, 0x10);
    NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.NoChildren);
    NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.UpdateNow | NativeMethods.RedrawWindowFlags.AllChildren);

1 个答案:

答案 0 :(得分:1)

您想要做的是违反Windows已制定的(复杂)规则,以防止行为不端的程序从用户手中夺走控制权。 (控制不仅仅意味着输入焦点,而且还控制可见和不可见的内容。)尽管您的意图可能与用户保持一致,但您要求的内容与破坏性程序通常尝试的内容无法区分。

alternative ways表示用户需要注意非前景窗口。例如,查看FlashWindowEx。您还可以考虑弹出notification balloons的托盘图标。这些似乎是适当而有效的解决方案。