【问题标题】:Find com-port used by serial mouse查找串行鼠标使用的 COM 端口
【发布时间】:2014-09-05 13:07:12
【问题描述】:

如何找到串口鼠标占用的串口

这是我在C# 中检测鼠标的方法(改编自answer 的代码)

var info = IntPtr.Zero;
try
{
    var guid = new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}"); // mouses
    info = SetupDiGetClassDevsW(ref guid, null, IntPtr.Zero, 0);
    if ((int)info == -1) // INVALID_HANDLE_VALUE
        throw new Exception(string.Format("Error({0}) SetupDiGetClassDevsW", Marshal.GetLastWin32Error()));
    // enumerate mouses
    var device = new SP_DEVINFO_DATA();
    device.cbSize = (UInt32)Marshal.SizeOf(device);
    for (uint i = 0; ; i++)
    {
        // get device info
        if (!SetupDiEnumDeviceInfo(info, i, out device))
        {
            var error = Marshal.GetLastWin32Error();
            if (error == 259) // ERROR_NO_MORE_ITEMS
                break;
            else
                throw new Exception(string.Format("Error({0}) SetupDiEnumDeviceInfo", error));
        }
        string id = GetStringPropertyForDevice(info, device, 1); // SPDRP_HARDWAREID
        if (id != null && id.Contains("*PNP0F09")) // Microsoft BallPoint Serial Mouse
        {
            // ...
            // here I want to check com-port, how?
            // ...
        }
    }
}
finally
{
    if (info != IntPtr.Zero)
        SetupDiDestroyDeviceInfoList(info);
}

编辑

删除C# 标签。寻找一般信息(任何语言)。

【问题讨论】:

  • 您是否尝试将 SPDRP_LOCATION_INFORMATION 或 SPDRP_LOCATION_PATHS 传递给您的 GetStringPropertyForDevice 函数? (来自msdn.microsoft.com/en-us/library/ff551967.aspx
  • @SimonMourier,我收到了ERROR_INVALID_DATA(我认为没问题,它只是意味着这个设备没有这样的属性)SPDRP_LOCATION_INFORMATION0xD)和SPDRP_LOCATION_PATHS(@ 987654331@).
  • 您所追求的属性实际上应该显示在“详细信息”选项卡中。你能检查它在你的配置中吗?
  • @SimonMourier,“详细信息”选项卡中的所有属性都不包含com6 之类的内容。我不知道 Windows 如何为此设备显示 com6。两者都不相反:如果我在尝试打开 com6 时遇到 UnauthorizedAccessException 异常(访问被拒绝 blablabla),则无法查看谁在使用它。
  • 没有评论的反对者应该去森林死。问题(截图)很清楚,问题似乎很合理:如何获取 Windows 为设备显示的不明显可获取的信息。

标签: windows device


【解决方案1】:

您可以使用 SysInternalSuite 中的 Process Monitor 并打开设备管理器,然后找出设备管理器从哪里获取其值

我在 USB 鼠标上尝试过,并且能够(在 USB 输入设备上)如下所示 1.打开鼠标属性(从控制面板) 2. 打开 ProcMon 3.点击目标图标,选择鼠标属性窗口 4. 从鼠标属性窗口打开硬件选项卡 5. 在 ProcMon 点击​​ File-> Captuer Events 6.在ProcMon Edit->Find并查找不带引号的“com” 7.双击找到的行(如果你能找到它)

另一种解决方案是使用设备管理器命令行实用程序 devcon 获取设备信息并解析输出流中的信息

关于 devcon 的更多信息: * http://support.microsoft.com/kb/311272 * https://superuser.com/questions/414280/how-do-i-view-a-list-of-devices-from-the-command-line-in-windows

希望有帮助

【讨论】:

  • 什么是地图?所以你建议我枚举系统中的串口,然后检查一下我的鼠标和我的端口是否......是什么?在财产之一或什么中具有相同的ID?想法似乎没问题,我只是不知道我到底应该做什么。那么,这个映射是什么?
  • 您能否发布您的 SerialPort 设备 ID 和鼠标设备 ID,同时看看第二个解决方案 (support.microsoft.com/kb/311272)
  • 检查一下,他从 SerialPort 获取设备名称:stackoverflow.com/questions/17170126/…
  • 我不知道如何使用 Process Monitor 让您的 Event Properties 窗口抱歉。你怀疑有一个注册表项,我会读吗? SerialBall 的Device description 是“@msmouse.inf,%*pnp0f09.devicedesc%;Serieller Microsoft BallPoint”,在注册表中找到,但它让我不知道如何从中获取 COM 端口。我在注册表中找不到“com6”或导致 com6。
  • 这不是我的 :) 我无法为串行鼠标验证它我没有(根据问题一般知识 - 只是想提供帮助)
【解决方案2】:

在设备管理器中生成“Location”字符串的子程序是devmgr.dll!GetLocationInformation

您感兴趣的路径 - 生成附加在括号中的值 - 可以用以下代码表示(基于 Hex-Rays 的反编译):

int __stdcall GetLocationInformation(DEVINST dnDevInst, wchar_t *lpsResult,
                                     int cchBufferMax, HMACHINE hMachine)
{
  int dwUiNumber;
  HKEY hKey;
  DWORD pulLength;
  wchar_t sRawLocationInfo[260];

  sRawLocationInfo[0] = 0;
  DWORD Type = REG_SZ;
  pulLength = 520;
  if ( !CM_Open_DevNode_Key_Ex(dnDevInst, KEY_READ, 0, 1u, &hKey, 1u, hMachine) )
  {
    RegQueryValueExW(hKey, L"LocationInformationOverride", 0, &Type,
      sRawLocationInfo, &pulLength);
    RegCloseKey(hKey);
  }
  if ( !sRawLocationInfo[0] )
  {
    pulLength = 520;
    CM_Get_DevNode_Registry_Property_ExW(
      dnDevInst,
      CM_DRP_LOCATION_INFORMATION,
      0,
      sRawLocationInfo,
      &pulLength,
      0,
      hMachine);
  }
  pulLength = 4;
  if ( CM_Get_DevNode_Registry_Property_ExW(
         dnDevInst,
         CM_DRP_UI_NUMBER,
         0,
         &dwUiNumber,
         &pulLength,
         0,
         hMachine)
    || pulLength <= 0 )
  {
    <...>   //this block always returns
  }
  else
  {
      <...>
      if ( sRawLocationInfo[0] )
      {
        lstrcatW(lpsResult, L" (");
        lstrcatW(lpsResult, sRawLocationInfo);
        lstrcatW(lpsResult, L")");
      }
      return 0;
  }
}

简而言之,括号中的值是设备节点的LocationInformationOverrideLocationInformation 属性,并且仅在UiNumber 属性不存在(或伪造)时生成。


CM_Open_DevNode_Key_ExCM_Get_DevNode_Registry_Property_ExW 函数在文档中被标记为“保留”。你可以


如果my guess 是对的,那么您在设备管理器中看到的“USB Serial Port (COM6)”实际上是父设备的名称(=在设备管理器中“查看设备”中看到的此设备所连接的设备通过连接”模式)。如果这是正确的,“COM6”只是名称的一部分,而不是一些独立的属性。

【讨论】:

  • 谢谢,但第一个使用的函数是CM_Open_DevNode_Key_ExCM_Get_DevNode_Registry_Property_ExW,我什至找不到。我想如何使用提供的信息来获取设备位置?我要invoke dll function吗?
  • P/Invoke,当然,导出的 DLL 函数总是如此。
  • 我现在使用SetupDiGetDeviceRegistryProperty。你说位置?我试过SPDRP_LOCATION_INFORMATION,但它返回ERROR_INVALID_DATA。如果你告诉我如何使用它,那么 那将是完美的答案。否则你的回答对我没有用:codeproject 中的一些代码,它使用 reserved 函数,不,谢谢。
  • 我只链接到函数原型的代码项目,sheesh。
  • 不要误会我的意思,我感谢您的努力。但是现在的状态就像是用中文写的:看起来花哨,解释很多,但仍然不知道如何使用它。
猜你喜欢
  • 2014-10-10
  • 2016-04-25
  • 2012-08-09
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 2013-03-29
  • 2021-01-28
  • 1970-01-01
相关资源
最近更新 更多