我有一个使用 TComport2010 执行 USB/COM 通信的 Delphi 桌面应用程序。此应用程序从 USB 设备读取坐标 X、Y 并在 Windows 桌面模拟鼠标上戳。一切正常,除了尝试移动 OSK 的窗口(在屏幕键盘上)时,此问题已通过以管理员权限或uiAccess = true
在清单上运行的应用程序得到解决,请参阅此处的讨论:OSK 访问问题
以及上面帖子中建议的解决方案,我可以在 OSK 上戳鼠标事件。但是,当使用以下清单运行应用程序时,TComport2010 无法在 comport 上写入,该清单只有 request uiAccess = true
,没有超级用户权限。
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="true"/>
</requestedPrivileges>
该应用程序是使用建议的清单编译的,已签名并在程序文件目录上运行,但是,在这种情况下,comport 失败,无法写入...如果我以管理员身份运行上下文菜单运行应用程序,那么一切正常,OSK 戳和 com 端口读/写。该应用程序需要某种权限才能访问 COM 设备?或者可能与 TComport 的注册表访问有关?完整清单在这里:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="pendrv.exe"
version="2.0.0.2552"
processorArchitecture="*" />
<description>Fixed Up App</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--This Id value indicates the application supports Windows 7 functionality-->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--This Id value indicates the application supports Windows 8 functionality-->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--This Id value indicates the application supports Windows 8.1 functionality-->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
</application>
</compatibility>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<applicationRequestMinimum>
<PermissionSet ID="FullTrust" Unrestricted="true" />
<defaultAssemblyRequest permissionSetReference="FullTrust" />
</applicationRequestMinimum>
<requestedPrivileges>
<!-- this access OSK but tcomport fails -->
<requestedExecutionLevel level="asInvoker" uiAccess="true"/>
<!-- in this case all works fine, but popup superuser request, that I want to avoid -->
<requestedExecutionLevel level="requireAdministrator" uiAccess="true"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
好吧,问题是为什么 TcomPort 不能与 manifest using only 一起使用uiAccess = true
,如下所示:
<requestedExecutionLevel level="asInvoker" uiAccess="true"/>
我运行应用程序签名并在程序文件文件夹中。
失败的delhpi代码是对comport上的writestr的调用,当使用asinvoker和uiaccess = true运行应用程序时,这会失败,当以管理员权限运行时,如果我将没有清单和任何权限的应用程序放在同一个文件夹上,它就可以工作com 工作也有效。相关的delphi代码如下:
com 组件不会增加设备发送的任何消息,我确定设备每 30 秒发送一个 msg,但 onrxchar 事件永远不会上升,调用 write 函数但不确定 msg 是否真的发送到设备。一般来说,当使用 asinvoker 和 uiaccess=true 运行时,windows 似乎会阻止设备和 delphi 组件之间的通信。如果我以管理员权限运行,则相同的代码可以完美运行。
我把tcomport的代码放在pastebin上,因为这里有大小限制,代码链接是:
在将一些日志消息写入备忘录字段后,当从外部 USB 设备接收一些数据时,我会跟踪 TComport 事件的正常循环。
这是正常读取/接收数据操作的周期:(以管理员身份运行)
TCOMLOG:-----CreateHandle OK-----
TCOMLOG:_WriteStrWrapper:<read_ch>=9
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:DoTxEmpty
TCOMLOG:Thread.execute
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:CallRxChar
TCOMLOG:DoRxChar call
TCOMLOG:ReadStr called
TCOMLOG:ReadAsync called
TCOMLOG:ReadAsync passed
TCOMLOG:ReadStr finished
TCOMLOG:Thread.execute
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:CallRxChar
TCOMLOG:DoRxChar call
TCOMLOG:ReadStr called
TCOMLOG:ReadAsync called
TCOMLOG:ReadAsync passed
TCOMLOG:ReadStr finished
TCOMLOG:Thread.execute
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:CallRxChar
TCOMLOG:DoRxChar call
TCOMLOG:ReadStr called
TCOMLOG:ReadAsync called
TCOMLOG:ReadAsync passed
TCOMLOG:ReadStr finished
TCOMLOG:Thread.execute
...
这是我在 Windows 的同一程序文件文件夹中仅使用 uiAccess=true 和 asInvoker 级别运行应用程序时的循环:
TCOMLOG:-----CreateHandle OK-----
TCOMLOG:_WriteStrWrapper:<read_ch>=9
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:DoTxEmpty
TCOMLOG:Thread.execute
TCOMLOG:Thread.DispathComMsg
TCOMLOG:Thread.DoEvents
TCOMLOG:CallRxChar
TCOMLOG:DoRxChar call
TCOMLOG:ReadStr called
TCOMLOG:ReadAsync called
TCOMLOG:ReadAsync passed
TCOMLOG:ReadStr
日志在 ReadStr 上停止,似乎是 thread.execute freeze 或其他什么,可能是由于未知原因,APP 没有从 windows 接收到 usb 事件。