RegisterRawInputDevices returning false

1

I am using RegisterRawInputDevices of user32.dll to register the keyboard, but it's returning false. I am developing an Office add-in using VSTO and C#.

[StructLayout(LayoutKind.Sequential)]
public struct RAWINPUTDEVICE
{
    [MarshalAs(UnmanagedType.U2)]
    public UInt16 usUsagePage;
    [MarshalAs(UnmanagedType.U2)]
    public UInt16 usUsage;
    [MarshalAs(UnmanagedType.U4)]
    public int dwFlags;
    public IntPtr hwndTarget;
}

[DllImport("User32.dll", SetLastError = true)]
public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice,
    UInt32 uiNumDevices, UInt32 cbSize);

[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

public void Register()
{
    IntPtr hwnd = FindWindow("PPTFrameClass", "Presentation1 - PowerPoint");
    RegisterKeyboardDevice(hwnd);
}

public void RegisterKeyboardDevice(IntPtr hwnd)
{
    const int RIDEV_INPUTSINK = 0x00000100;
    RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
    rid[0].usUsagePage = Convert.ToUInt16(1);
    rid[0].usUsage = Convert.ToUInt16(6);
    rid[0].dwFlags = RIDEV_INPUTSINK;
    rid[0].hwndTarget = hwnd;
    if (!RegisterRawInputDevices(rid, Convert.ToUInt32(rid.Length),
        Convert.ToUInt32(Marshal.SizeOf(rid[0]))))
    {
        throw new ApplicationException("Failed to register raw input device(s). " +
            "Error code: " + Marshal.GetLastWin32Error());
    }
}

But the same logic is working fine for VB.NET and COM-addins. Please correct me if I am going wrong.

c#
vsto
asked on Stack Overflow Oct 24, 2016 by Abhinav Srivastava • edited Oct 28, 2016 by haindl

1 Answer

0

You can call RegisterRawInputDevices only on windows that belong to the same process as your calling code.

I tested your code in an Excel C# VSTO addin as well as in an Excel C# COM addin and in both cases I could successfully call RegisterRawInputDevices on the Excel window itself and on a WPF test window, that was created from inside the addin, without any kind of error. (My version for this test was Excel 2016 64-bit.)

Unfortunately I don't have any kind of reference for this behavior but I think this is intentional by design, maybe because of security concerns as you could potentially hijack some other window and possibly act as a kind of keylogger or doing some other really bad stuff.

So your code does work perfectly but you have to use a window that belongs to the same process. And I think the difference to your VB.NET addin is that it's working because it's playing by this rule.

answered on Stack Overflow Oct 28, 2016 by haindl

User contributions licensed under CC BY-SA 3.0