为什么Windows的SetCursorPos在某些程序在前台时无效?

Why is Windows's SetCursorPos ineffective when certain programs are in foreground?

win32 API 的 SetCursorPos 将鼠标移动到屏幕上的某个位置。但是,有时它什么都不做。

见以下C++代码(Visual Studio16.8.1,Windows10)

#include <iostream>
#include <windows.h>

int main()
{
    while (true)
    {
        std::cout << "Hello World!\n";
        SetCursorPos(100, 200);
        Sleep(2000);
    }
}

每 2 秒,如果 SetCursorPos 有效,则光标传送到 (100, 200)。这可以正常工作。

但是,如果我离开这个 运行 并打开名为“屏幕键盘”的内置 Windows 应用程序,SetCursorPos 将不再有效(光标不再每次传送2 秒)。
注意:如果您自己尝试,屏幕键盘通常会自动取消焦点。为了让它专注于观察 SetCursorPos 不工作,alt+tab 到它,这导致它不会自行散焦。

还有其他第三方应用程序在前台运行时似乎也会阻碍 SetCursorPos。 (当我观察这些时,我没有使用上面的 C++ 脚本。我使用的是 Python 包 mouse,它在后台使用 SetCursorPos。)

这些应用程序如何“吞噬”我的 SetCursorPos API 调用,我是否可以使用不同的 API 或技术来代替SetCursorPos 不允许那些应用程序干扰?


物理 USB 鼠标以及远程桌面软件(如 TeamViewer 和 Anydesk)不受此类应用程序的阻碍,这让我相信它们利用 SetCursorPos 之外的一些途径来获得可靠的鼠标移动。

答案是管理员权限。

正如@chris 在评论中所解释的那样,一些程序具有更高的权限,当它们在前台(因此接受用户输入)时,Windows 不允许程序 without 提升权限控制鼠标或键盘。否则,不受信任的程序将能够利用受信任的程序来执行不受信任的程序通常不允许执行的操作。

这样想。不应该允许没有 FBI 安全许可的巫师对 FBI 特工使用夺魂咒来有效地获得许可。

查看其他人在评论中提供的这些链接:relevant SO post #1, relevant SO post #2, tangential Windows accessibility article

解决方法:运行你的鼠标控制程序也提升了权限。

例如,如果 运行在 Cmd 中运行您的程序,请以管理员身份打开 Cmd,方法是右键单击“开始”菜单或任务栏中的 Cmd 图标,然后 select“运行作为管理员”,然后 运行 你的脚本在里面。如果您的程序是批处理文件,您可以右键单击它的快捷方式并选择“运行 as admin”。