由于UIPI,SendInput失败

时间:2013-07-15 00:34:40

标签: c# certificate sendinput uipi

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

[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来模拟click事件然后抛出异常。

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

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

  

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

     

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

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

任何人都可以帮我解决这个问题吗?

0 个答案:

没有答案