Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetDoubleClickTime returns 0 unexpectedly

We found a problem in our software with some customers after they upgraded their Windows 10 installation to version 2004 (May 2020 Update).

Server-side code in a webservice application creates a DevExpress PDF Viewer control and this failed with the error message "Interval cannot be 0". (I know creating a visual control inside a webservice is not a good idea, but this is legacy code and not trivial to change).

An analysis showed that the problem is that the control tries to create a .net WinForms Timer component and setting its Interval property to the result of SystemInformation.DoubleClickTime (which is just a wrapper for the GetDoubleClickTime winapi function). The error happens because the DoubleClickTime value is unexpectedly 0.

Why does this happen and is there some workaround?

like image 884
NineBerry Avatar asked Jan 24 '23 19:01

NineBerry


1 Answers

The Windows API function “GetDoubleClickTime” is used to query the maximum number of milliseconds between two mouse clicks so that the two clicks are counted as one double click instead.

In Windows 10 Version 2004 this function unexpectedly returns 0 when executed in the context of a batch login, which means for example:

  • Code inside a Windows service
  • Code in applications that are started from a Windows service
  • Server-side code in web applications in IIS
  • Code in applications started from “planned tasks” in Windows with the setting “Run whether user is logged on or not”

In all these cases, there is no user interface. Executed code (in my case it is very old legacy code that doesn’t have a separation between user interface and business rules yet) could still query the value and then fail if 0 is returned unexpectedly. In my case, for example, a third party user interface control is instantiated which fails when trying to set a .net Windows Forms Timer based on the system double click time.

The same scenario returned values > 0 in Windows 10 before the update to Version 2004.

How to reproduce the bug

Using the following simple C# application

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);
        }
    }
}

Use the Microsoft Tool DebugView (with the setting “Capture Global Win32” enabled) to see the output from Trace.WriteLine.

Then create a Task in the Windows Task Scheduler to execute the compiled application. Use the setting “Run whether user is logged on or not”. You will see the output is

DoubleClickTime: 0

If you execute the compiled application directly, you will see the correct output

DoubleClickTime: 500

(Or some other value depending on your mouse settings).

In previous Windows 10 versions, a value higher than 0 was returned in both cases.

The same effect can be seen when code runs in a Windows service or in a web application in an IIS application pool. Probably also in other cases whenever code runs in the context of a batch logon.

How to solve the issue

  • Wait for Microsoft to fix the issue in a future update.
  • Advise customers to not install the Windows 10 2004 update or return to the previous Windows 10 version if necessary
  • Patch your code and make sure it can handle the case that GetDoubleClickTime returns 0. If necessary, contact vendors of third-party libraries to patch their libraries.

References

I have also published this as a blog post:

  • Bug in Windows 10 Version 2004: GetDoubleClickTime unexpectedly returns 0 when Batch Login is used

DevExpress is publishing a patch to their PDF Viewer component:

  • A PdfViewer instance cannot be created if the SystemInformation.DoubleClickTime environment variable returns 0
like image 78
NineBerry Avatar answered Jan 29 '23 10:01

NineBerry