10

我正在尝试在 Win7 上模拟鼠标事件,我的应用程序使用网站http://inputsimulator.codeplex.com/上的开源项目“Windows Input Simulator”,该项目在内部使用以下代码来模拟鼠标事件:

[DllImport("user32.dll", SetLastError = true)]
public static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] inputs, Int32 sizeOfInputStructure);

当我使用 Visual Studio 2010 调试它时,我的应用程序运行完美。左键单击事件、右键单击事件和鼠标移动事件都可以。但是当我通过双击 .exe 应用程序可执行文件从资源管理器启动我的应用程序时,单击事件不会发送。只有鼠标移动事件是可以的,如果我尝试模拟左键单击或右键单击,我的应用程序将收到异常并退出。我发现异常是由以下代码引发的:

public void DispatchInput(INPUT[] inputs)
{
    if (inputs == null) throw new ArgumentNullException("inputs");
    if (inputs.Length == 0) throw new ArgumentException("The input array was empty", "inputs");
    var successful = NativeMethods.SendInput((UInt32)inputs.Length, inputs, Marshal.SizeOf(typeof (INPUT)));
    if (successful != inputs.Length)
            throw new Exception("Some simulated input commands were not sent successfully. The most common reason for this happening are the security features of Windows including User Interface Privacy Isolation (UIPI). Your application can only send commands to applications of the same or lower elevation. Similarly certain commands are restricted to Accessibility/UIAutomation applications. Refer to the project home page and the code samples for more information.");
}

这表示 UIPI 阻止了 SendInput(...)。所以我谷歌这个话题,并得到一些建议。

1) 将 uiAccess="true" 添加到我的应用程序清单中

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

2) 创建一个测试证书并将此证书添加到本地机器受信任的根证书颁发机构证书存储和受信任的发布者证书存储。

MakeCert -r -pe -ss PrivateCertStore -n "CN=Test Certificate - For Internal Use Only" testcert.cer
CertMgr.exe /add testcert.cer /s /r localMachine root
CertMgr.exe /add testcert.cer /s /r localMachine trustedpublisher

3) 用以前的数字签名签署我的申请

SignTool sign /v /s PrivateCertStore /n "Test Certificate - For Internal Use Only" /t http://timestamp.verisign.com/scripts/timestamp.dll MyApplication.exe

4) 将我的应用程序安装到“C:\Program Files”文件夹,这是我计算机上的安全位置之一。

我想我已经做了所有的事情来满足 UIPI 的要求,但是在我启动我的应用程序并同意 UAC 提示后问题仍然没有解决。只有鼠标移动事件是可以的。

PS:如果我不使用测试证书签署我的应用程序,并且只在清单中添加带有 uiAccess="true" 的“requestedExecutionLevel”,应用程序将无法启动,并且 Windows 会显示一个对话框,其中包含消息“从服务器返回了一个推荐。”。如果我用测试证书签署了我的应用程序,UAC 将在我开始我的应用程序时工作。该应用程序将一直工作,直到我调用 SendInput 来模拟单击事件然后抛出异常。

我已经在http://msdn.microsoft.com/en-us/library/bb625963.aspx阅读了有关“接口特权隔离 (UIPI) 和完整性”的要求,但是在完成所有这些操作之后,仍然无法正常工作。

我找到了一个博客,在这个博客中,它说

通过在 [应用程序清单] 的 requestedPrivileges 属性中指定 UIAccess=”true”,应用程序要求绕过 UIPI 对跨权限级别发送窗口消息的限制。Windows Vista 在启动具有 UIAccess 权限的应用程序之前实施以下策略检查。应用程序必须具有可以使用数字证书验证的数字签名,该数字证书链接到本地​​计算机受信任的根证书颁发机构证书存储中的受信任的根。应用程序必须安装在只能由管理员写入的本地文件夹应用程序目录中,例如 Program Files 目录。

不幸的是,如果您的应用程序可以由非管理员用户安装,这将不起作用。

我想知道如何使我的应用程序不符合最后一句“不幸的是,如果您的应用程序可以由非管理员用户安装,这将不起作用”并且可以通过在清单中添加 uiAccess="true" 来绕过 UIPI。

任何人都可以帮助我吗?

4

0 回答 0