-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] GetRawInputDeviceInfo can not use CharSet = CharSet.Auto #439
Comments
Will you share your code? I have run this under 32 and 64-bit, with Unicode character sets without problem. uint nDev = 0;
Assert.That(GetRawInputDeviceList(null, ref nDev, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))), ResultIs.Not.Value(uint.MaxValue));
Assert.That(nDev, Is.GreaterThan(0));
RAWINPUTDEVICELIST[] devs = new RAWINPUTDEVICELIST[(int)nDev];
Assert.That(nDev = GetRawInputDeviceList(devs, ref nDev, (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICELIST))), ResultIs.Not.Value(uint.MaxValue));
Assert.That(nDev, Is.GreaterThan(0));
for (int i = 0; i < nDev; i++)
{
uint sz = 0;
Assert.That(GetRawInputDeviceInfo(devs[i].hDevice, RIDI.RIDI_DEVICENAME, default, ref sz), ResultIs.Value(0));
SafeLPTSTR data = new((int)sz + 1);
Assert.That(GetRawInputDeviceInfo(devs[i].hDevice, RIDI.RIDI_DEVICENAME, data, ref sz), Is.GreaterThan(0));
TestContext.WriteLine($"{data}");
} |
Sample codes here:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Vanara.PInvoke.Kernel32" Version="3.4.17" />
<PackageReference Include="Vanara.PInvoke.User32" Version="3.4.17" />
</ItemGroup>
</Project>
using System.Runtime.InteropServices;
using Vanara.PInvoke;
namespace ConsoleUser32;
internal class Program
{
static void Main()
{
EnumerateDevices();
}
internal static void EnumerateDevices()
{
uint deviceCount = 0;
int dwSize = Marshal.SizeOf(typeof(RawInputDeviceList));
if (User32.GetRawInputDeviceList(null, ref deviceCount, (uint)dwSize) == 0)
{
User32.RAWINPUTDEVICELIST[] pRawInputDeviceList = new User32.RAWINPUTDEVICELIST[deviceCount];
User32.GetRawInputDeviceList(pRawInputDeviceList, ref deviceCount, (uint)dwSize);
for (int i = 0; i < deviceCount; i++)
{
uint pcbSize = 0;
User32.RAWINPUTDEVICELIST rid = pRawInputDeviceList[i];
User32.GetRawInputDeviceInfo(rid.hDevice, (uint)RawInputDeviceInfo.RIDI_DEVICENAME, IntPtr.Zero, ref pcbSize);
if (pcbSize <= 0) continue;
// --------------------------------------
// All right
//nint pDataX = Marshal.AllocHGlobal((int)pcbSize);
//User32X.GetRawInputDeviceInfo((nint)rid.hDevice, RawInputDeviceInfo.RIDI_DEVICENAME, pDataX, ref pcbSize);
//string? deviceNameX = Marshal.PtrToStringAnsi(pDataX);
//Console.WriteLine(deviceNameX);
//Marshal.FreeHGlobal(pDataX);
// --------------------------------------
// --------------------------------------
// Application crash
nint pData = Marshal.AllocHGlobal((int)pcbSize);
User32.GetRawInputDeviceInfo(rid.hDevice, (uint)RawInputDeviceInfo.RIDI_DEVICENAME, pData, ref pcbSize);
string? deviceName = Marshal.PtrToStringAuto(pData);
Console.WriteLine(deviceName);
Marshal.FreeHGlobal(pData);
// --------------------------------------
}
}
}
}
file static class User32X
{
[DllImport("User32.dll", SetLastError = true)]
public static extern uint GetRawInputDeviceInfo(nint hDevice, RawInputDeviceInfo command, nint pData, ref uint size);
}
[StructLayout(LayoutKind.Sequential)]
file struct RawInputDeviceList
{
public nint Device;
public uint Type;
}
file enum RawInputDeviceInfo : uint
{
RIDI_DEVICENAME = 0x20000007,
RIDI_DEVICEINFO = 0x2000000b,
PREPARSEDDATA = 0x20000005
} |
You have a small bug in the code due to an odd use by the API of a variable. The docs say:
When calling |
I ajust to |
Error Code:
And then Marshal.PtrToStringAuto will get the error device name or some time will make application crash when in Chinese OS.
Like this issuse #428
I use following code to fix it.
correct code:
The text was updated successfully, but these errors were encountered: