40

我正在开发一种通过(虚拟)串行端口与 PC 通信的设备。问题是我们发送的数据偶尔会被 Windows 错误地识别为总线鼠标,之后加载“Microsoft Serial Ballpoint”驱动程序,鼠标指针开始在屏幕上跳跃并随机点击。

一些谷歌搜索表明这是串行设备的一个古老而众所周知的问题,通常的解决方法是一些注册表黑客来禁用有问题的驱动程序。然而,我们的用户有很多要求,我宁愿不要让我们的应用程序弄乱用户的注册表。尤其是当修复依赖于 Windows 版本并且用户很可能正在使用总线鼠标时。

相反,我想通过更改我们的协议以不发送任何可能使我们被误认为鼠标的数据来避免这个问题。唯一的问题是我不太确定要避免哪些模式。显然,微软的鼠标协议由四个字节的数据包组成,其中第一个的 MSB 已设置,后三个的 MSB 是明确的。

只发送 7 位 ASCII 就足够了吗?我还需要担心被检测为其他设备吗?

4

9 回答 9

35

我自己刚刚遇到了这个问题Windows 7 Professional x64,一个对我有用的解决方案是进入注册表并编辑以下值:

Location: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\sermouse  
Key: Start  
Value: 3

更改Value4,它将停止此问题的发生。

以下是所有有效起始值的列表

0 Boot (loaded by kernel loader). Components of the driver stack for the boot (startup) volume must be loaded by the kernel loader.

1 System (loaded by I/O subsystem). Specifies that the driver is loaded at kernel initialization.

2 Automatic (loaded by Service Control Manager). Specifies that the service is loaded or started automatically.

3 Manual. Specifies that the service does not start until the user starts it manually, such as by using Device Manager.

4 Disabled. Specifies that the service should not be started.

reg 编辑命令如下:

REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\sermouse" /V Start /T REG_DWORD /F /D 4

然后您需要重新启动计算机,它现在应该可以正确启动并且不会尝试发现串行鼠标。

祝你好运。

于 2012-06-13T01:34:38.717 回答
8

事实证明,Windows 中的鼠标检测通常由serenum.sys过滤器驱动程序处理。该驱动程序实现了对传统串行鼠标以及串行即插即用的支持。Microsoft 甚至提供了源代码作为 WDK 示例

在检测过程中,端口切换到 1200-7-N-1 模式,同时断言DTR+ RTS,预计将在 200 毫秒内响应,并在发生故障时重试几次。不幸的是,对于传统鼠标来说,一个M或一个B字符就足以作为标识。

在我们的例子中,协议被重新设计以避免这些字符,现在似乎不再被错误识别了。

但是,我们使用的是虚拟 USB 串行端口,而对于传统串行端口,这种方法可能有些困难,因为以不同波特率发送的任何内容都可能看起来像线路噪声。在这种情况下,我认为最简单的解决方法可能是,正如已经建议的那样,避免进行任何未经请求的传输。

或者,串行控制信号实际连接或被 USB CDC 设备拦截,处理DTRRTS信号并延迟输出。实际上实现即插即用协议将是一个更好的选择。据说周围有便宜的 RS232 电缆,但没有完整的控制信号,所以这种方法可能仍然会失败。

于 2014-09-23T09:55:32.597 回答
5

我也遇到了这个问题,通过在 FTDI 驱动程序的高级属性(设备管理器中的 COM 端口属性)中禁用“串行枚举器”来修复它。这在http://www.ftdichip.com/Support/Documents/AppNotes/AN_107_AdvancedDriverOptions_AN_000073.pdf中有描述。

于 2015-02-04T21:38:35.440 回答
4

我自己也遇到过这个 Windows 错误。这是我自己对该主题的研究:

Microsoft 承认此错误: http: //support.microsoft.com/kb/819036 开始下载他们的工具,看看它是否解决了问题。

  • 下载并安装他们的程序。
  • 从 C:\program\Microsoft comdisable\ 从命令提示符运行它
  • comdisable /list执行程序时写入。
  • 将显示计算机上的所有端口。
  • comdisable /disable COMx其中 x 是端口号。
  • 对计算机上的所有端口执行此操作。
  • 重启。

这应该有望成为一个通用的解决方案。

或者,您可以破解 boot.ini,但我不相信这在 Vista/Win 7 中有效。我有一些来自 Cisco 系统的应用说明,描述了如何执行此操作。如果以上方法不能解决您的问题,请告诉我。

于 2012-02-13T09:28:28.470 回答
2

在我的开发环境中,我只是从设备管理器中禁用了Microsoft 串行鼠标。

这似乎解决了我的问题的罪魁祸首。在此之前,CH340G我在设计中使用的芯片DTR在开始连接之前会降低五倍,有效地重新启动我的基于 Arduino 的电路板并使其无用。

Microsoft 串行鼠标驱动程序与 Arduino Clone 的 CH340G UART 转 USB 冲突

于 2018-02-05T01:32:33.293 回答
1

也许这有帮助:我们在使用 FTDI FT232RL 时遇到了同样的问题。我们发现这是我们 PCB 的硬件问题。

FTDI 数据表中提到了#RESET-Pin:低电平有效复位引脚。这可以被外部设备用来复位 FT232R。如果不需要,可以不连接,或上拉至 VCC。

我们的应用程序不需要 RESET-Pin,因此我们通过 1k Pull-Up 将其连接到 Vcc。似乎#RESET-Pin 的上拉导致 FT232RL 未定义启动,至少每隔一个转换器,我们连接到 USB 插座会导致设备管理器中的串行球点。我们移除了#RESET-Pin 处的上拉电阻,因此#RESET-Pin 未连接。从那时起,每个接口都可以正常工作,并且不再在 Windows 设备管理器中创建串行球点。

于 2013-05-14T12:57:32.537 回答
1

如果你有一个“真正的”串行端口,或者一个 USB 加密狗(RS-232、RS-485,没关系),这个问题可以通过首先用终端或任何应用程序打开有问题的串行端口来解决想要监控它,然后才插入设备。为了您自己,您还应该注意在终止连接之前移除设备。

将 FTDI 芯片焊接在设备本身上,你就完蛋了。我花了几轮来解释这样的管理,即设备本身通信与焊接在 PCB 上的 FTDI 芯片配对,Windows 计算机不太可能通过用户友好性,无论 USB 插座看起来多么光滑柜子上……(谢天谢地,所有这些情况都非常罕见和不寻常)

于 2014-09-22T18:54:15.357 回答
1

自 2010 年以来,我在将串行刻度头连接到 PC 时遇到了这个问题。Usb 到串行转换器与否.. 我只使用 SILABS 设备的 CP2102 或类似设备.. 我通过简单地允许安装驱动程序然后在设备管理器中查找鼠标/HIDA 下的圆珠笔驱动程序然后简单地禁用驱动程序来解决它, 不要卸载它只是禁用它。然后,即使安装了驱动程序,当您重新启动时,Windows 似乎也会将 comport 视为串行鼠标并使用输入中的数据。您还会发现,如果圆珠笔驱动程序处于活动状态,那么 COMport 正在使用中,有时会返回一个无法访问的 COM PORT...希望这对那里的一些人有所帮助 :) Tx Ben

于 2016-12-22T18:32:40.420 回答
0

用于阻止 GPS 被检测为串行鼠标的代码。

下面是 C#.net 中子例程的代码。它检查注册表项是否设置为 4,如果没有,它会发出配置命令来禁用 sermouse。将此子程序嵌入在启动时运行的程序中,它将在 Windows 更新后更正设置。

如果您在此问题一次又一次发生时感到恼火,可能会很有用

私人无效 Stop_sermouse()

    {
        string k =
        "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\sermouse";

        object v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
        if (v==null)
            {
            MessageBox.Show("No Registry Key for sermouse");
                }
        else
        {
            string sr = v.ToString();
            if (sr == "4")
            {; }
            else
            {
                DialogResult mbox = MessageBox.Show("disable sermouse ? " + v.ToString(), "Found sermouse enabled! ", MessageBoxButtons.YesNo);
                if (mbox == DialogResult.Yes)
                { 
                    // prepare a small job to issue confuguration command
        ProcessStartInfo s = new ProcessStartInfo("cmd.exe", "/c sc config sermouse start=disabled");
                    Process p = new Process();
                    s.Verb = "runas"; // Must run as administrator
                    s.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    p.StartInfo = s;
        // and run the command
                    p.Start();
        //check if the registry is modified indeed
                    v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
                    sr = v.ToString();
                    if (sr == "4")
                    {
                        MessageBox.Show("finished ''sc config sermouse start=disabled'' but not succesfull in registry!");
                    }
                    else
                    {
                        MessageBox.Show("sermouse is disabled");
                    }
                }
            }
        }           
    }
于 2020-06-09T06:48:31.753 回答