User32.DLL SetFocus因Win32错误5而失败:访问被拒绝

时间:2012-04-20 12:30:25

标签: c# pinvoke access-denied user32

以下代码执行以下操作

PushWindowToFront():

  • 获取当前进程ID以供稍后参考
  • 使用回调 EnumWindowsCallback 方法调用user32.dll函数 EnumWindows
  • 然后,EnumWindows遍历每个窗口并为每个
  • 调用回调

回调:

  • 检查窗口线程进程ID是否与当前进程ID相同
  • 如果是,请检查窗口文本是否开始“选择”
  • 如果是这样,在窗口句柄上调用user32.dll函数SetFocus
  • check&打印最后一次win32错误

然而,它总是返回win32错误5 - “访问被拒绝”。为什么应用程序无法访问属于同一进程的窗口调用此函数?

    public void PushWindowToFront()
    {
        currentProcessId = System.Diagnostics.Process.GetCurrentProcess().Id;

        Win32Methods.EnumWindowsCallbackDelegate callback = new Win32Methods.EnumWindowsCallbackDelegate(this.EnumWindowsCallback);

        Win32Methods.EnumWindows(callback, (IntPtr) 0);
    }

    public bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
    {
        uint i = 0;

        Win32Methods.GetWindowThreadProcessId(hWnd, out i);

        if (currentProcessId == i)
        {

            StringBuilder sb = new StringBuilder(512);

            Win32Methods.GetWindowText(hWnd, sb, sb.Capacity);

            if (sb.ToString().Split(' ')[0].ToLower().Equals("select"))
            {
                IntPtr result = Win32Methods.SetFocus(hWnd);
                Console.WriteLine("Window found: {0}\r\nSetting focus...\r\nResult: {1}\r\nLastError: {2}",
                    sb.ToString(), result, Marshal.GetLastWin32Error().ToString());
            }
        }

        return true;
    }

1 个答案:

答案 0 :(得分:2)

我收到了这个确切的情况;我的理解是“SetFocus”是罪魁祸首。我通过将“SetFocus”替换为“SetForegroundWindow”

来解决错误
hwnd = win32gui.FindWindow(None, winName)
win32gui.SetForegroundWindow(hwnd)