I try to enable/disable a specific USB device with C#. I am a very confused because i found a lot informations, and they all contradict each other. My first question is, the "setupapi.dll" just works in 32 bit plataform? Anyway, my program return false when calling:
bool rstl2 = DeviceHelper.SetupDiCallClassInstaller(DeviceHelper.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
My source code:
public bool HW_Set_State( bool bEnable)
{
try
{
Guid myGUID = new Guid("{745a17a0-74d3-11d0-b6fe-00a0c90f57da}");
IntPtr hDevInfo = DeviceHelper.SetupDiGetClassDevs(ref myGUID, 0, IntPtr.Zero, DeviceHelper.DIGCF_ALLCLASSES | DeviceHelper.DIGCF_PRESENT);
try
{
if (hDevInfo.ToInt32() == DeviceHelper.INVALID_HANDLE_VALUE)
return false;
} catch { }
if (hDevInfo.ToInt64() == DeviceHelper.INVALID_HANDLE_VALUE)
return false;
DeviceHelper.SP_DEVINFO_DATA DeviceInfoData;
DeviceInfoData = new DeviceHelper.SP_DEVINFO_DATA();
DeviceInfoData.cbSize = 28;
DeviceInfoData.devInst = 0;
DeviceInfoData.classGuid = myGUID;
DeviceInfoData.reserved = 0;
UInt32 i;
StringBuilder DeviceName = new StringBuilder("");
DeviceName.Capacity = DeviceHelper.MAX_DEV_LEN;
for (i = 0; DeviceHelper.SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)
{
if(DeviceHelper.SetupDiGetDeviceRegistryProperty(hDevInfo, DeviceInfoData, DeviceHelper.SPDRP_DEVICEDESC, 0, DeviceName, DeviceHelper.MAX_DEV_LEN, IntPtr.Zero)){
if (DeviceName.ToString().Contains("USB Input Device"))
{
if (DeviceInfoData.classGuid.ToString().Contains("745a17a0-74d3-11d0-b6fe-00a0c90f57da"))
{
ChangeDeviceState(hDevInfo, DeviceInfoData, bEnable);
}
}
}
}
DeviceHelper.SetupDiDestroyDeviceInfoList(hDevInfo);
}
catch (Exception ex)
{
return false;
}
return true;
}
}
private bool ChangeDeviceState(IntPtr hDevInfo, DeviceHelper.SP_DEVINFO_DATA devInfoData, bool bEnable)
{
try
{
int szOfPcp;
IntPtr ptrToPcp;
int szDevInfoData;
IntPtr ptrToDevInfoData;
DeviceHelper.SP_PROPCHANGE_PARAMS pcp = new DeviceHelper.SP_PROPCHANGE_PARAMS();
if (bEnable)
{
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(DeviceHelper.SP_CLASSINSTALL_HEADER));
pcp.ClassInstallHeader.InstallFunction = DeviceHelper.DIF_PROPERTYCHANGE;
pcp.StateChange = DeviceHelper.DICS_ENABLE;
pcp.Scope = DeviceHelper.DICS_FLAG_GLOBAL;
pcp.HwProfile = 0;
szOfPcp = Marshal.SizeOf(pcp);
ptrToPcp = Marshal.AllocHGlobal(szOfPcp);
Marshal.StructureToPtr(pcp, ptrToPcp, true);
szDevInfoData = Marshal.SizeOf(devInfoData);
ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);
if (DeviceHelper.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(DeviceHelper.SP_PROPCHANGE_PARAMS))))
{
DeviceHelper.SetupDiCallClassInstaller(DeviceHelper.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
}
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(DeviceHelper.SP_CLASSINSTALL_HEADER));
pcp.ClassInstallHeader.InstallFunction = DeviceHelper.DIF_PROPERTYCHANGE;
pcp.StateChange = DeviceHelper.DICS_ENABLE;
pcp.Scope = DeviceHelper.DICS_FLAG_CONFIGSPECIFIC;
pcp.HwProfile = 0;
}
else
{
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(DeviceHelper.SP_CLASSINSTALL_HEADER));
pcp.ClassInstallHeader.InstallFunction = DeviceHelper.DIF_PROPERTYCHANGE;
pcp.StateChange = DeviceHelper.DICS_DISABLE;
pcp.Scope = DeviceHelper.DICS_FLAG_CONFIGSPECIFIC;
pcp.HwProfile = 0;
}
szOfPcp = Marshal.SizeOf(pcp);
ptrToPcp = Marshal.AllocHGlobal(szOfPcp);
Marshal.StructureToPtr(pcp, ptrToPcp, true);
szDevInfoData = Marshal.SizeOf(devInfoData);
ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);
Marshal.StructureToPtr(devInfoData, ptrToDevInfoData, true);
bool rslt1 = DeviceHelper.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(DeviceHelper.SP_PROPCHANGE_PARAMS)));
bool rstl2 = DeviceHelper.SetupDiCallClassInstaller(DeviceHelper.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
if ((!rslt1) || (!rstl2))
{
return false;
}
else
{
return true;
}
}
catch (Exception ex)
{
return false;
}
}
If I wrote something wrong, I'm sorry. Im from Brazil :)
If you also prefer using WMI you can do it like this:
*Install Management NuGet
using System.Management;
*Add string with your device name/guid/deviceid.etc
public string DeviceName = "YourDeviceName";
*For Enable
ManagementObjectSearcher myDevices = new ManagementObjectSearcher("root\\CIMV2", @"SELECT * FROM Win32_PnPEntity where Name Like " + '"' + DeviceName + '"');
foreach (ManagementObject item in myDevices.Get())
{
ManagementBaseObject UWFEnable = item.InvokeMethod("Enable", null, null);
}
*For Disable
ManagementObjectSearcher myDevices = new ManagementObjectSearcher("root\\CIMV2", @"SELECT * FROM Win32_PnPEntity where Name Like " + '"' + DeviceName + '"');
foreach (ManagementObject item in smyDevices.Get())
{
ManagementBaseObject inParams = item.InvokeMethod("Disable", null, null);
}
@Edit: You can also use devcon.exe from the Microsoft website.