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

当我拥有UIAccess权限时,为什么SetWindowPos无法将窗口置于z顺序的前面?(Windows 7),windows,uac,z-order,uia,Windows,Uac,Z Order,Uia,SetWindowPos无法将外部进程的窗口可靠地置于z顺序的顶部,这使我遇到了问题。我可以把窗户放在前面,比如: NativeMethods.SetWindowPos(hwnd, new IntPtr(-1), Left, Top, Width, Height, 0x10); NativeMethods.SetWindowPos(hwnd, new IntPtr(-2), Left, Top, Width, Height, 0x10); 但它并不是在100%的时间里都能工

SetWindowPos无法将外部进程的窗口可靠地置于z顺序的顶部,这使我遇到了问题。我可以把窗户放在前面,比如:

     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" />

您想要做的是违反Windows的(复杂的)规则,以防止行为不好的程序从用户手中夺取控制权。(控制不仅仅意味着关注输入,还意味着控制什么是可见的,什么是不可见的。)尽管你的意图可能与用户的意图一致,但你所要求的与破坏性程序经常试图做的是无法区分的


有一些方法可以向用户发出信号,表示非前台窗口需要注意。例如,退房。您也可以考虑弹出一个托盘图标。这些似乎是合适而有效的解决方案。

您想要做的事情与Windows为防止行为不好的程序从用户手中夺走控制权而制定的(复杂)规则背道而驰。(控制不仅仅意味着关注输入,还意味着控制什么是可见的,什么是不可见的。)尽管你的意图可能与用户的意图一致,但你所要求的与破坏性程序经常试图做的是无法区分的


有一些方法可以向用户发出信号,表示非前台窗口需要注意。例如,退房。您也可以考虑弹出一个托盘图标。这些似乎是合适而有效的解决方案。

为什么你的应用程序需要提升,为什么你要将uiAccess设置为true?我的程序是一个扑克自动化程序。它将需要注意的表放在zorder的顶部,以便用户可以对其进行操作。我使用了一种方法,通过将setwindowpos设置为最顶层,然后设置为非顶层,使其正常工作。但它不够可靠。我需要一种在所有时间都有效的方法。我解释了为什么我觉得我需要在主岗位上获得UIAccess的原因。你不能得到什么工作。你能给我们一些背景资料吗?对不起,大卫,我无意中输入了我的评论。我已经更新了它。我认为这篇文章可能很有启发性。为什么你的应用程序需要提升,为什么你要将uiAccess设置为true?我的程序是一个扑克自动化程序。它将需要注意的表放在zorder的顶部,以便用户可以对其进行操作。我使用了一种方法,通过将setwindowpos设置为最顶层,然后设置为非顶层,使其正常工作。但它不够可靠。我需要一种在所有时间都有效的方法。我解释了为什么我觉得我需要在主岗位上获得UIAccess的原因。你不能得到什么工作。你能给我们一些背景资料吗?对不起,大卫,我无意中输入了我的评论。我已经更新了。我想这篇文章可能会很有启发性。谢谢你的回复。这似乎是普遍的共识,但为什么我发布的文档中会有相反的说法?我不认为我删掉了上下文或误解了它。您没有发布指向您引用的文档的链接,所以我搜索并找到了以下内容:。在更广泛的上下文中,这篇文章是关于UIAccess如何允许进程绕过UIPI的。UIAccess不会覆盖设置前景窗口的常规限制。相反,它允许在目标进程处于更高完整性级别的情况下应用现有规则。您的问题不是完整性级别,而是关于谁可以设置前台窗口以及何时设置的基本规则。感谢您的回复。这似乎是普遍的共识,但为什么我发布的文档中会有相反的说法?我不认为我删掉了上下文或误解了它。您没有发布指向您引用的文档的链接,所以我搜索并找到了以下内容:。在更广泛的上下文中,这篇文章是关于UIAccess如何允许进程绕过UIPI的。UIAccess不会覆盖设置前景窗口的常规限制。相反,它允许在目标进程处于更高完整性级别的情况下应用现有规则。您的问题不是完整性级别,而是关于谁可以设置前台窗口以及何时设置的基本规则。
    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);