Search code examples
c#clipboardsendkeys

Paste current time using global hotkey in C#


I am trying to paste current time in any windows using C#. So I defined a global hotkey in C# and when I press the hotkey in any windows, the current time is pasted there.

The issue is that it works perfectly with Notepad, but in Notepad++ it pastes the current time just once and then after that it pastes some strange character which is shown by SYN in Notepad++. I added a thread.sleep(500); before paste command and it works in every windows.

So the question is that why without delay it works in Notepad and not in Notepad++? and how I can get rid of the sleep delay in order to make it works in every windows?

Thanks in advance.

here is my code:

    public static void PasteDT()
    {
        ClipPut(DateTime.Now.ToString("HHmmss"));
        //Thread.Sleep(500); //<< without this line it works just once in Notepad++
        SendKeys.SendWait("^v");
    }

    public static void ClipPut(string ClipboardText)
    {
        Thread clipboardThread = new Thread(() => Clipboard.SetText(ClipboardText));
        clipboardThread.SetApartmentState(ApartmentState.STA);
        clipboardThread.IsBackground = false;
        clipboardThread.Start();
        clipboardThread.Join();
    }

Solution

  • The issue is with the SendKeys.Send is processed by Notepad++ when the hotkey is pressed. If the hotkey already has a function in Notepad++, or it conflicts then you get undefined behaviour.

    The reason why the sleep is working is because it gives you time to release the initial triggering hotkey, and then Notepad++ processes the paste command correctly.

    I don't believe there is a way to resolve this using SendKeys, you can however use SendInput, which gets queued by the application and processed on the "hotkey up".

    In the past, when I've had to send keys to applications I have used Input Simulator, which internally wraps the low level Win32 SendInput calls. The resultant code in your case would be:

    //...
    Thread clipboardThread = new Thread(() =>
    {
        Clipboard.SetText(ClipboardText);
    });
    clipboardThread.SetApartmentState(ApartmentState.STA);
    clipboardThread.IsBackground = false;
    clipboardThread.Start();
    clipboardThread.Join();
    
    InputSimulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V);
    //...