(view source code of hashid.cs as plain text)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace RobvanderWoude{internal class HasHID
{static readonly string progver = "1.00";
static int Main( string[] args )
{bool usbkeyboards = true;
bool otherkeyboards = true;
bool quietmode = false;
bool mice = true;
bool kbds = true;
#region Parse Command Lineforeach ( string arg in args )
{switch ( arg.ToUpper( ) )
{case "/?":
return ShowHelp( );
case "/K":
case "/KBD":
case "/KEYBOARD":
case "/KEYBOARDS":
if ( !mice )
{return ShowHelp( "Duplicate command line switch /KEYBOARD" );
}mice = false;
break;
case "/M":
case "/MOUSE":
case "/MICE":
if ( !kbds )
{return ShowHelp( "Duplicate command line switch /MOUSE" );
}kbds = false;
usbkeyboards = false;
otherkeyboards = false;
break;
case "/O":
case "/OTHER":
if ( !kbds )
{return ShowHelp( "Switch /OTHER is not valid with /MOUSE" );
}else if ( !usbkeyboards )
{return ShowHelp( "Duplicate command line switch /OTHER" );
}usbkeyboards = false;
break;
case "/Q":
case "/QUIET":
if ( quietmode )
{return ShowHelp( "Duplicate command line switch /QUIET" );
}quietmode = true;
break;
case "/U":
case "/USB":
if ( !kbds )
{return ShowHelp( "Switch /USB is not valid with /MOUSE" );
}else if ( !otherkeyboards )
{return ShowHelp( "Duplicate command line switch /USB" );
}otherkeyboards = false;
break;
default:
return ShowHelp( "Invalid command line argument \"{0}\"", arg );
}if ( !mice && !kbds )
{return ShowHelp( "Command line switches /KEYBOARD and /MOUSE are mutually exclusive" );
}if ( !kbds && ( otherkeyboards || usbkeyboards ) )
{return ShowHelp( "Switches /USB or /OTHER are not valid with /MOUSE" );
}else if ( kbds && ( !otherkeyboards && !usbkeyboards ) )
{return ShowHelp( "Command line switches /USB and /OTHER are mutually exclusive" );
} } #endregion Parse Command Line #region Enumerate and Count Raw Input Devicesvar rawDeviceEnumerator = new RawInputDeviceEnumerator( );
int count = -1;
if ( kbds && mice )
{count = rawDeviceEnumerator.AllKeyboardsCount;
int tempcount = count;
tempcount = rawDeviceEnumerator.AllMiceCount;
if ( !quietmode )
{Console.WriteLine( "Total keyboards count: {0}", count );
Console.WriteLine( "Total mice count: {0}", tempcount );
}count += tempcount;
}else if ( mice )
{count = rawDeviceEnumerator.AllMiceCount;
if ( !quietmode )
{Console.WriteLine( "Total mice count: {0}", count );
} }else if ( kbds && ( otherkeyboards && usbkeyboards ) )
{count = rawDeviceEnumerator.AllKeyboardsCount;
if ( !quietmode )
{Console.WriteLine( "Total keyboards count: {0}", count );
} }else if ( usbkeyboards )
{count = rawDeviceEnumerator.UsbKeyboardsCount;
if ( !quietmode )
{Console.WriteLine( "USB keyboards count: {0}", count );
} }else if ( otherkeyboards )
{count = rawDeviceEnumerator.OtherKeyboardsCount;
if ( !quietmode )
{Console.WriteLine( "Other (non-USB) keyboards count: {0}", count );
} } #endregion Enumerate and Count Raw Input Devicesreturn count;
}public static int ShowHelp( params string[] errmsg )
{ #region Error Messageif ( errmsg.Length > 0 )
{List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
} #endregion Error Message #region Help Text /* HasHID.exe, Version 1.00 Count number of mice and/or keyboards available at this very moment Usage: HasHID.exe [ /MOUSE | /KEYBOARD [ /USB | /OTHER ] ] [ /Q ] Where: /MOUSE count mice only (default: mice and keyboards) /KEYBOARD count keyboards only (default: mice and keyboards) /USB count USB keyboards only (default: all keyboards) /OTHER count OTHER (non-USB) keyboards only (default: all) /QUIET QUIET mode (no screen output) Notes: By default this program counts all mice and keyboards. Switches may be abbreviated to /K, /M, /U, /O and/or /Q. The program's return code equals the number of devices of the specified type detected, or -1 in case of (command line) errors. Credits: Based on C# wrapper for GetRawInputDeviceList by Pavel Pachobut https://github.com/PashaPash/RawInput/ Written by Rob van der Woude https://www.robvanderwoude.com */ #endregion Help Text #region Display Help TextConsole.Error.WriteLine( );
Console.Error.WriteLine( "HasHID.exe, Version {0}", progver );
Console.Error.WriteLine( "Count number of mice and/or keyboards available at this very moment" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "HasHID.exe [ /MOUSE | /KEYBOARD [ /USB | /OTHER ] ] [ /Q ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/MOUSE" );
Console.ResetColor( );
Console.Error.Write( " count " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "mice" );
Console.ResetColor( );
Console.Error.WriteLine( " only (default: mice and keyboards)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /KEYBOARD" );
Console.ResetColor( );
Console.Error.Write( " count " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "keyboards" );
Console.ResetColor( );
Console.Error.WriteLine( " only (default: mice and keyboards)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /USB" );
Console.ResetColor( );
Console.Error.Write( " count " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "USB" );
Console.ResetColor( );
Console.Error.WriteLine( " keyboards only (default: all keybords)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /OTHER" );
Console.ResetColor( );
Console.Error.Write( " count " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "OTHER" );
Console.ResetColor( );
Console.Error.WriteLine( " (non-USB) keyboards only (default: all)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /QUIET QUIET" );
Console.ResetColor( );
Console.Error.WriteLine( " mode (no screen output)" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Notes: By default this program counts all mice and keyboards." );
Console.Error.Write( " Switches may be abbreviated to " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/K" );
Console.ResetColor( );
Console.Error.Write( ", " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/M" );
Console.ResetColor( );
Console.Error.Write( ", " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/U" );
Console.ResetColor( );
Console.Error.Write( ", " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/O" );
Console.ResetColor( );
Console.Error.Write( " and/or " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/Q" );
Console.ResetColor( );
Console.Error.WriteLine( "." );
Console.Error.WriteLine( " The program's return code equals the number of devices of the" );
Console.Error.WriteLine( " specified type detected, or -1 in case of (command line) errors." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Credits: Based on C# wrapper for GetRawInputDeviceList by Pavel Pachobut" );
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Error.WriteLine( " https://github.com/PashaPash/RawInput/" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Textreturn -1;
} } // The following code is copied from Pavel Pachobut's C# wrapper for // GetRawInputDeviceList: https://github.com/PashaPash/RawInput/ // and modified by Rob van der Woude (added AllKeyboardsCount, AllMiceCount // and OtherKeyboardsCount properties to RawInputDeviceEnumerator class)public class RawInputDevice
{private readonly Win32.RawInputDeviceList _rawInputDeviceList;
private readonly string _deviceName;
private readonly Win32.DeviceInfo _deviceInfo;
public IntPtr DeviceHandle { get {return _rawInputDeviceList.DeviceHandle;
} }public Win32.RawInputDeviceType DeviceType
{ get {return _rawInputDeviceList.DeviceType;
} }public string DeviceName
{ get {return this._deviceName;
} }public Win32.DeviceInfo DeviceInfo
{ get {return this._deviceInfo;
} }public RawInputDevice( Win32.RawInputDeviceList rawInputDeviceList )
{this._rawInputDeviceList = rawInputDeviceList;
_deviceName = GetDeviceName( this._rawInputDeviceList.DeviceHandle );
_deviceInfo = GetDeviceInfo( this._rawInputDeviceList.DeviceHandle );
}private static IntPtr GetDeviceData( IntPtr deviceHandle, Win32.RawInputDeviceInfoCommand command )
{uint dataSize = 0;
var ptrData = IntPtr.Zero;
Win32.GetRawInputDeviceInfo( deviceHandle, command, ptrData, ref dataSize );
if ( dataSize == 0 )
{return IntPtr.Zero;
}ptrData = Marshal.AllocHGlobal( (int)dataSize );
var result = Win32.GetRawInputDeviceInfo( deviceHandle, command, ptrData, ref dataSize );
if ( result == 0 )
{Marshal.FreeHGlobal( ptrData );
return IntPtr.Zero;
}return ptrData;
}private static string GetDeviceName( IntPtr deviceHandle )
{var ptrDeviceName = GetDeviceData( deviceHandle, Win32.RawInputDeviceInfoCommand.DeviceName );
if ( ptrDeviceName == IntPtr.Zero )
{return string.Empty;
}var deviceName = Marshal.PtrToStringAnsi( ptrDeviceName );
Marshal.FreeHGlobal( ptrDeviceName );
return deviceName;
}private static Win32.DeviceInfo GetDeviceInfo( IntPtr deviceHandle )
{var ptrDeviceInfo = GetDeviceData( deviceHandle, Win32.RawInputDeviceInfoCommand.DeviceInfo );
if ( ptrDeviceInfo == IntPtr.Zero )
{return new Win32.DeviceInfo( );
}var deviceInfo = (Win32.DeviceInfo)Marshal.PtrToStructure( ptrDeviceInfo, typeof( Win32.DeviceInfo ) );
Marshal.FreeHGlobal( ptrDeviceInfo );
return deviceInfo;
} }public class RawInputDeviceEnumerator
{private readonly RawInputDevice[] _devices;
public IEnumerable<RawInputDevice> Devices
{ get {return this._devices;
} }public RawInputDeviceEnumerator( )
{uint deviceCount = 0;
var deviceSize = (uint)Marshal.SizeOf( typeof( Win32.RawInputDeviceList ) );
// first call retrieves the number of raw input devicesvar result = Win32.GetRawInputDeviceList( IntPtr.Zero, ref deviceCount, deviceSize );
_devices = new RawInputDevice[deviceCount];
if ( (int)result == -1 || deviceCount == 0 )
{ // call failed, or no devices foundreturn;
} // allocates memory for an array of Win32.RawInputDeviceListIntPtr ptrDeviceList = Marshal.AllocHGlobal( (int)( deviceSize * deviceCount ) );
result = Win32.GetRawInputDeviceList( ptrDeviceList, ref deviceCount, deviceSize );
if ( (int)result != -1 )
{ // enumerates array of Win32.RawInputDeviceList, // and populates array of managed RawInputDevice objectsfor ( var index = 0; index < deviceCount; index++ )
{var rawInputDeviceList = (Win32.RawInputDeviceList)Marshal.PtrToStructure( new IntPtr( ( ptrDeviceList.ToInt32( ) + ( deviceSize * index ) ) ), typeof( Win32.RawInputDeviceList ) );
_devices[index] = new RawInputDevice( rawInputDeviceList );
} }Marshal.FreeHGlobal( ptrDeviceList );
}public int AllMiceCount
{ get {return this.Devices.Count( d => d.DeviceType == Win32.RawInputDeviceType.Mouse );
} }public int AllKeyboardsCount
{ get {return this.Devices.Count( d => d.DeviceType == Win32.RawInputDeviceType.Keyboard );
} }public int OtherKeyboardsCount
{ get {return this.Devices.Count( d => d.DeviceType == Win32.RawInputDeviceType.Keyboard && !d.DeviceInfo.KeyboardInfo.IsUSBKeboard );
} }public int UsbKeyboardsCount
{ get {return this.Devices.Count( d => d.DeviceType == Win32.RawInputDeviceType.Keyboard && d.DeviceInfo.KeyboardInfo.IsUSBKeboard );
} } }public static class Win32
{public enum RawInputDeviceType : uint
{Mouse = 0,
Keyboard = 1,
HumanInterfaceDevice = 2
}public enum RawInputDeviceInfoCommand : uint
{ PreparsedData = 0x20000005, DeviceName = 0x20000007, DeviceInfo = 0x2000000b, }[StructLayout( LayoutKind.Explicit )]
public struct DeviceInfo
{[FieldOffset( 0 )]
public int Size;
[FieldOffset( 4 )]
public int Type;
[FieldOffset( 8 )]
public DeviceInfoMouse MouseInfo;
[FieldOffset( 8 )]
public DeviceInfoKeyboard KeyboardInfo;
[FieldOffset( 8 )]
public DeviceInfoHID HIDInfo;
}public struct DeviceInfoMouse
{public uint ID;
public uint NumberOfButtons;
public uint SampleRate;
}public struct DeviceInfoKeyboard
{public uint Type;
public uint SubType;
public uint KeyboardMode;
public uint NumberOfFunctionKeys;
public uint NumberOfIndicators;
public uint NumberOfKeysTotal;
public bool IsUSBKeboard
{ get {return this.Type == 81; // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724336%28v=vs.85%29.aspx
} } }public struct DeviceInfoHID
{public uint VendorID;
public uint ProductID;
public uint VersionNumber;
public ushort UsagePage;
public ushort Usage;
}[StructLayout( LayoutKind.Sequential )]
public struct RawInputDeviceList
{public IntPtr DeviceHandle;
public RawInputDeviceType DeviceType;
}[DllImport( "User32.dll", SetLastError = true )]
public static extern uint GetRawInputDeviceList( IntPtr pRawInputDeviceList, ref uint uiNumDevices, uint cbSize );
[DllImport( "user32.dll", SetLastError = true )]
public static extern uint GetRawInputDeviceInfo( IntPtr hDevice, RawInputDeviceInfoCommand uiCommand, IntPtr data, ref uint size );
}}page last modified: 2025-10-11; loaded in 0.0133 seconds