Search code examples
c#usbdllimport

How to enable/Disabe an USB device specific with C#


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 :)


Solution

  • 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.