winapi - GetDoubleClickTime 意外返回 0
问题描述
在一些客户将其 Windows 10 安装升级到版本 2004(2020 年 5 月更新)后,我们发现我们的软件存在问题。
Web 服务应用程序中的服务器端代码创建 DevExpress PDF 查看器控件,但失败并显示错误消息“间隔不能为 0”。(我知道在 Web 服务中创建可视化控件不是一个好主意,但这是遗留代码,更改起来并不简单)。
分析表明,问题在于控件试图创建一个 .net WinFormsTimer
组件并将其Interval
属性设置为结果SystemInformation.DoubleClickTime
(这只是GetDoubleClickTime
winapi 函数的包装器)。发生错误是因为该DoubleClickTime
值意外地为 0。
为什么会发生这种情况,是否有一些解决方法?
解决方案
Windows API 函数“GetDoubleClickTime”用于查询两次鼠标单击之间的最大毫秒数,以便将两次单击计为一次双击。
在Windows 10 版本 2004中,此函数在批量登录的上下文中执行时意外返回 0,这意味着例如:
- Windows 服务中的代码
- 从 Windows 服务启动的应用程序中的代码
- IIS 中 Web 应用程序中的服务器端代码
- 应用程序中的代码从 Windows 中的“计划任务”开始,设置为“无论用户是否登录都运行”</li>
在所有这些情况下,都没有用户界面。执行的代码(在我的例子中,它是非常旧的遗留代码,还没有将用户界面和业务规则分开)仍然可以查询该值,然后如果意外返回 0 则失败。例如,在我的情况下,第三方用户界面控件被实例化,当尝试根据系统双击时间设置 .net Windows 窗体计时器时失败。
在更新到版本 2004 之前,相同的方案在 Windows 10 中返回值 > 0。
如何重现错误
使用以下简单的 C# 应用程序
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace WindowsFormsApp14
{
static class Program
{
[DllImport("user32.dll")]
static extern uint GetDoubleClickTime();
[STAThread]
static void Main()
{
// Same result with var doubleClickTime =
// System.Windows.Forms.SystemInformation.DoubleClickTime;
var doubleClickTime = GetDoubleClickTime();
Trace.WriteLine("DoubleClickTime: " + doubleClickTime);
}
}
}
使用 Microsoft 工具DebugView(启用“Capture Global Win32”设置)查看 Trace.WriteLine 的输出。
然后在 Windows 任务计划程序中创建一个任务来执行编译后的应用程序。使用设置“无论用户是否登录都运行”。你会看到输出是
双击时间:0
如果直接执行编译后的应用程序,你会看到正确的输出
双击时间:500
(或其他值,具体取决于您的鼠标设置)。
在以前的 Windows 10 版本中,在这两种情况下都返回了高于 0 的值。
当代码在 Windows 服务或 IIS 应用程序池中的 Web 应用程序中运行时,可以看到相同的效果。可能在其他情况下,只要代码在批处理登录的上下文中运行。
如何解决问题
- 等待 Microsoft 在未来的更新中解决此问题。
- 建议客户不要安装 Windows 10 2004 更新或在必要时返回到以前的 Windows 10 版本
- 为您的代码打补丁并确保它可以处理 GetDoubleClickTime 返回 0 的情况。如有必要,请联系第三方库的供应商以修补他们的库。
参考
我也将此作为博客文章发布:
DevExpress 正在为其 PDF 查看器组件发布补丁:
推荐阅读
- angular - 无法读取角度未定义的属性“原型”
- ios - 使用 macintouch 将 .ipa 上传到苹果商店
- c# - Chromedriver 正在阻止摄像头。仅在第一个窗口中有效
- android - 如何让我的 React-Native Android 项目为 64 位架构做好准备?
- mysql - 预订系统删除一段时间内所有已保存的预订
- c# - 如何通过firebase基于xamarin表单中的时间发送推送通知
- azure-devops - 在 VSTS 中的 CI 构建中配置 Sonarqube 分析
- ios - 从 ios 网站发出 ios 通知
- java - JMeter Post 请求 - JSON 解析错误:无效的 UTF-8 起始字节 0xb0
- c - 使用 strcpy、strcat、sprintf 将 3 个字符串组合在一起至少一次