GetDoubleClickTime 意外返回 0

Nin*_*rry 4 winapi double-click windows-10

在一些客户将 Windows 10 安装升级到版本 2004(2020 年 5 月更新)后,我们发现我们的软件存在问题。

Web 服务应用程序中的服务器端代码创建 DevExpress PDF 查看器控件,但失败并显示错误消息“间隔不能为 0”。(我知道在 Web 服务内创建可视化控件不是一个好主意,但这是遗留代码,更改起来并不容易)。

分析表明,问题在于该控件尝试创建一个 .net WinFormsTimer组件并将其Interval属性设置为SystemInformation.DoubleClickTime(这只是GetDoubleClickTimewinapi 函数的包装器)的结果。发生错误是因为该DoubleClickTime值意外为 0。

为什么会发生这种情况?有解决方法吗?

Nin*_*rry 5

Windows API 函数 \xe2\x80\x9cGetDoubleClickTime\xe2\x80\x9d 用于查询两次鼠标单击之间的最大毫秒数,以便将两次单击计为一次双击。

\n

Windows 10 版本 2004中,在批量登录上下文中执行时,此函数意外返回 0,这意味着:

\n
    \n
  • Windows 服务内的代码
  • \n
  • 从 Windows 服务启动的应用程序中的代码
  • \n
  • IIS 中 Web 应用程序中的服务器端代码
  • \n
  • 应用程序中的代码从 Windows 中的 \xe2\x80\x9c 计划任务\xe2\x80\x9d 启动,\n设置 \xe2\x80\x9c无论用户是否登录\xe2\x80\x9d 都运行\xe2\x80\x9d
  • \n
\n

在所有这些情况下,都没有用户界面。执行的代码(在我的例子中,它是非常旧的遗留代码,\xe2\x80\x99 在用户界面和业务规则之间还没有分离)仍然可以查询该值,如果意外返回 0,则失败。例如,在我的例子中,实例化了一个第三方用户界面控件,当尝试根据系统双击时间设置 .net Windows 窗体计时器时,该控件会失败。

\n

在更新到版本 2004 之前,相同的情况在 Windows 10 中返回值 > 0。

\n

如何重现该错误

\n

使用以下简单的 C# 应用程序

\n
using System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\n\nnamespace WindowsFormsApp14\n{\n \n    static class Program\n    {\n        [DllImport("user32.dll")]\n        static extern uint GetDoubleClickTime();\n         \n        [STAThread]\n        static void Main()\n        {\n            // Same result with var doubleClickTime = \n            // System.Windows.Forms.SystemInformation.DoubleClickTime;\n            var doubleClickTime = GetDoubleClickTime();\n \n            Trace.WriteLine("DoubleClickTime: " + doubleClickTime);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用 Microsoft 工具DebugView(启用 \xe2\x80\x9cCapture Global Win32\xe2\x80\x9d 设置)查看 Trace.WriteLine 的输出。

\n

然后在 Windows 任务计划程序中创建一个任务来执行编译后的应用程序。无论用户是否登录,都使用设置 \xe2\x80\x9cRun\xe2\x80\x9d。你会看到输出是

\n
\n

双击时间:0

\n
\n

如果直接执行编译后的应用程序,您将看到正确的输出

\n
\n

双击时间:500

\n
\n

(或其他一些值,具体取决于您的鼠标设置)。

\n

在以前的 Windows 10 版本中,这两种情况都会返回大于 0 的值。

\n

当代码在 Windows 服务或 IIS 应用程序池中的 Web 应用程序中运行时,可以看到相同的效果。在其他情况下,只要代码在批量登录的上下文中运行,也可能如此。

\n

如何解决问题

\n
    \n
  • 等待微软在未来的更新中修复该问题。
  • \n
  • 建议客户不要安装Windows 10 2004更新或在必要时返回到以前的Windows 10版本
  • \n
  • 修补您的代码并确保它可以处理 GetDoubleClickTime 返回 0 的情况。如有必要,请联系第三方库的供应商以修补其库。
  • \n
\n

参考

\n

我还将其发布为博客文章:

\n\n

DevExpress 正在发布其 PDF 查看器组件的补丁:

\n\n