¿Cómo desactivo un dispositivo de sistema programáticamente?

Estoy buscando la forma de desactivar un dispositivo del sistema (ya sea USB o interno) en C # .NET dado el PID y VID o el nombre del dispositivo.

Después de buscar, encontré la Biblioteca de Hardware Helper para C # en CodeProject.

Pero necesito algo que funcione en XP, Vista y Windows 7 (sistemas operativos x86 y x64) … el proyecto que he vinculado solo funciona con XP y Vista x86 … incluso cuando se ejecuta la aplicación con privilegios de administrador.

¿Alguien sabe de una solución que funcionaría en todos los sistemas operativos?

Parece que hay dos cosas en la versión de drf que te están causando problemas. Su problema x64 fue causado por SP_DEVINFO_DATA que tenía un error donde se necesitaba un IntPtr. El segundo es que la función SetupDiGetDevicePropertyW es Vista + y no se ejecutará en XP.

Aquí hay una versión con esos dos problemas corregidos. Probé como x86 y AnyCPU en XPx86 y Win7X64.

public static class DisableHardware { const uint DIF_PROPERTYCHANGE = 0x12; const uint DICS_ENABLE = 1; const uint DICS_DISABLE = 2; // disable device const uint DICS_FLAG_GLOBAL = 1; // not profile-specific const uint DIGCF_ALLCLASSES = 4; const uint DIGCF_PRESENT = 2; const uint ERROR_INVALID_DATA = 13; const uint ERROR_NO_MORE_ITEMS = 259; const uint ERROR_ELEMENT_NOT_FOUND = 1168; static DEVPROPKEY DEVPKEY_Device_DeviceDesc; static DEVPROPKEY DEVPKEY_Device_HardwareIds; [StructLayout(LayoutKind.Sequential)] struct SP_CLASSINSTALL_HEADER { public UInt32 cbSize; public UInt32 InstallFunction; } [StructLayout(LayoutKind.Sequential)] struct SP_PROPCHANGE_PARAMS { public SP_CLASSINSTALL_HEADER ClassInstallHeader; public UInt32 StateChange; public UInt32 Scope; public UInt32 HwProfile; } [StructLayout(LayoutKind.Sequential)] struct SP_DEVINFO_DATA { public UInt32 cbSize; public Guid classGuid; public UInt32 devInst; public IntPtr reserved; // CHANGE #1 - was UInt32 } [StructLayout(LayoutKind.Sequential)] struct DEVPROPKEY { public Guid fmtid; public UInt32 pid; } [DllImport("setupapi.dll", SetLastError = true)] static extern IntPtr SetupDiGetClassDevsW( [In] ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, IntPtr parent, UInt32 flags); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, UInt32 memberIndex, [Out] out SP_DEVINFO_DATA deviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiSetClassInstallParams( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA deviceInfoData, [In] ref SP_PROPCHANGE_PARAMS classInstallParams, UInt32 ClassInstallParamsSize); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiChangeState( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA deviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiGetDevicePropertyW( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA DeviceInfoData, [In] ref DEVPROPKEY propertyKey, [Out] out UInt32 propertyType, IntPtr propertyBuffer, UInt32 propertyBufferSize, out UInt32 requiredSize, UInt32 flags); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiGetDeviceRegistryPropertyW( IntPtr DeviceInfoSet, [In] ref SP_DEVINFO_DATA DeviceInfoData, UInt32 Property, [Out] out UInt32 PropertyRegDataType, IntPtr PropertyBuffer, UInt32 PropertyBufferSize, [In,Out] ref UInt32 RequiredSize ); static DisableHardware() { DisableHardware.DEVPKEY_Device_DeviceDesc = new DEVPROPKEY(); DEVPKEY_Device_DeviceDesc.fmtid = new Guid( 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0); DEVPKEY_Device_DeviceDesc.pid = 2; DEVPKEY_Device_HardwareIds = new DEVPROPKEY(); DEVPKEY_Device_HardwareIds.fmtid = new Guid( 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0); DEVPKEY_Device_HardwareIds.pid = 3; } public static void DisableDevice(Func filter, bool disable = true) { IntPtr info = IntPtr.Zero; Guid NullGuid = Guid.Empty; try { info = SetupDiGetClassDevsW( ref NullGuid, null, IntPtr.Zero, DIGCF_ALLCLASSES); CheckError("SetupDiGetClassDevs"); SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA(); devdata.cbSize = (UInt32)Marshal.SizeOf(devdata); // Get first device matching device criterion. for (uint i = 0; ; i++) { SetupDiEnumDeviceInfo(info, i, out devdata); // if no items match filter, throw if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) CheckError("No device found matching filter.", 0xcffff); CheckError("SetupDiEnumDeviceInfo"); string devicepath = GetStringPropertyForDevice(info, devdata, 1); // SPDRP_HARDWAREID // Uncomment to print name/path //Console.WriteLine(GetStringPropertyForDevice(info, // devdata, DEVPKEY_Device_DeviceDesc)); //Console.WriteLine(" {0}", devicepath); if (devicepath != null && filter(devicepath)) break; } SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER(); header.cbSize = (UInt32)Marshal.SizeOf(header); header.InstallFunction = DIF_PROPERTYCHANGE; SP_PROPCHANGE_PARAMS propchangeparams = new SP_PROPCHANGE_PARAMS(); propchangeparams.ClassInstallHeader = header; propchangeparams.StateChange = disable ? DICS_DISABLE : DICS_ENABLE; propchangeparams.Scope = DICS_FLAG_GLOBAL; propchangeparams.HwProfile = 0; SetupDiSetClassInstallParams(info, ref devdata, ref propchangeparams, (UInt32)Marshal.SizeOf(propchangeparams)); CheckError("SetupDiSetClassInstallParams"); SetupDiChangeState( info, ref devdata); CheckError("SetupDiChangeState"); } finally { if (info != IntPtr.Zero) SetupDiDestroyDeviceInfoList(info); } } private static void CheckError(string message, int lasterror = -1) { int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror; if (code != 0) throw new ApplicationException( String.Format("Error disabling hardware device (Code {0}): {1}", code, message)); } private static string GetStringPropertyForDevice(IntPtr info, SP_DEVINFO_DATA devdata, uint propId) { uint proptype, outsize; IntPtr buffer = IntPtr.Zero; try { uint buflen = 512; buffer = Marshal.AllocHGlobal((int)buflen); outsize=0; // CHANGE #2 - Use this instead of SetupDiGetDeviceProperty SetupDiGetDeviceRegistryPropertyW( info, ref devdata, propId, out proptype, buffer, buflen, ref outsize); byte[] lbuffer = new byte[outsize]; Marshal.Copy(buffer, lbuffer, 0, (int)outsize); int errcode = Marshal.GetLastWin32Error(); if (errcode == ERROR_INVALID_DATA) return null; CheckError("SetupDiGetDeviceProperty", errcode); return Encoding.Unicode.GetString(lbuffer); } finally { if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); } } } 

Se puede hacer utilizando los métodos P / Invoke en la API de instalación de Windows. Las funciones de API han estado en Windows desde W2K. Las llamadas API pueden requerir derechos administrativos. A continuación se muestra un código aproximado para usar estas API para desactivar (y habilitar) los dispositivos en C #, que permiten invocar:

  DisableDevice( n => n.ToUpperInvariant().Contains("VID_3F20&PID_8A1D"), true); // true disables the device, false enables it 

El primer parámetro es un filtro que se pasa la identificación del hardware. Esto desactiva o habilita el primer dispositivo que coincide con el filtro provisto. No hay efecto si el dispositivo ya está en el estado objective.

El código sigue

 public static class DisableHardware { const uint DIF_PROPERTYCHANGE = 0x12; const uint DICS_ENABLE = 1; const uint DICS_DISABLE = 2; // disable device const uint DICS_FLAG_GLOBAL = 1; // not profile-specific const uint DIGCF_ALLCLASSES = 4; const uint DIGCF_PRESENT = 2; const uint ERROR_NO_MORE_ITEMS = 259; const uint ERROR_ELEMENT_NOT_FOUND = 1168; static DEVPROPKEY DEVPKEY_Device_DeviceDesc; static DEVPROPKEY DEVPKEY_Device_HardwareIds; [StructLayout(LayoutKind.Sequential)] struct SP_CLASSINSTALL_HEADER { public UInt32 cbSize; public UInt32 InstallFunction; } [StructLayout(LayoutKind.Sequential)] struct SP_PROPCHANGE_PARAMS { public SP_CLASSINSTALL_HEADER ClassInstallHeader; public UInt32 StateChange; public UInt32 Scope; public UInt32 HwProfile; } [StructLayout(LayoutKind.Sequential)] struct SP_DEVINFO_DATA { public UInt32 cbSize; public Guid classGuid; public UInt32 devInst; public UInt32 reserved; } [StructLayout(LayoutKind.Sequential)] struct DEVPROPKEY { public Guid fmtid; public UInt32 pid; } [DllImport("setupapi.dll", SetLastError = true)] static extern IntPtr SetupDiGetClassDevsW( [In] ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, IntPtr parent, UInt32 flags); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, UInt32 memberIndex, [Out] out SP_DEVINFO_DATA deviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiSetClassInstallParams( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA deviceInfoData, [In] ref SP_PROPCHANGE_PARAMS classInstallParams, UInt32 ClassInstallParamsSize); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiChangeState( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA deviceInfoData); [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiGetDevicePropertyW( IntPtr deviceInfoSet, [In] ref SP_DEVINFO_DATA DeviceInfoData, [In] ref DEVPROPKEY propertyKey, [Out] out UInt32 propertyType, IntPtr propertyBuffer, UInt32 propertyBufferSize, out UInt32 requiredSize, UInt32 flags); static DisableHardware() { DisableHardware.DEVPKEY_Device_DeviceDesc = new DEVPROPKEY(); DEVPKEY_Device_DeviceDesc.fmtid = new Guid( 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0); DEVPKEY_Device_DeviceDesc.pid = 2; DEVPKEY_Device_HardwareIds = new DEVPROPKEY(); DEVPKEY_Device_HardwareIds.fmtid = new Guid( 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0); DEVPKEY_Device_HardwareIds.pid = 3; } public static void DisableDevice(Func filter, bool disable = true) { IntPtr info = IntPtr.Zero; Guid NullGuid = Guid.Empty; try { info = SetupDiGetClassDevsW( ref NullGuid, null, IntPtr.Zero, DIGCF_ALLCLASSES); CheckError("SetupDiGetClassDevs"); SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA(); devdata.cbSize = (UInt32)Marshal.SizeOf(devdata); // Get first device matching device criterion. for (uint i = 0; ; i++) { SetupDiEnumDeviceInfo(info, i, out devdata); // if no items match filter, throw if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) CheckError("No device found matching filter.", 0xcffff); CheckError("SetupDiEnumDeviceInfo"); string devicepath = GetStringPropertyForDevice(info, devdata, DEVPKEY_Device_HardwareIds); // Uncomment to print name/path //Console.WriteLine(GetStringPropertyForDevice(info, // devdata, DEVPKEY_Device_DeviceDesc)); //Console.WriteLine(" {0}", devicepath); if (devicepath != null && filter(devicepath)) break; } SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER(); header.cbSize = (UInt32)Marshal.SizeOf(header); header.InstallFunction = DIF_PROPERTYCHANGE; SP_PROPCHANGE_PARAMS propchangeparams = new SP_PROPCHANGE_PARAMS(); propchangeparams.ClassInstallHeader = header; propchangeparams.StateChange = disable ? DICS_DISABLE : DICS_ENABLE; propchangeparams.Scope = DICS_FLAG_GLOBAL; propchangeparams.HwProfile = 0; SetupDiSetClassInstallParams(info, ref devdata, ref propchangeparams, (UInt32)Marshal.SizeOf(propchangeparams)); CheckError("SetupDiSetClassInstallParams"); SetupDiChangeState( info, ref devdata); CheckError("SetupDiChangeState"); } finally { if (info != IntPtr.Zero) SetupDiDestroyDeviceInfoList(info); } } private static void CheckError(string message, int lasterror = -1) { int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror; if (code != 0) throw new ApplicationException( String.Format("Error disabling hardware device (Code {0}): {1}", code, message)); } private static string GetStringPropertyForDevice(IntPtr info, SP_DEVINFO_DATA devdata, DEVPROPKEY key) { uint proptype, outsize; IntPtr buffer = IntPtr.Zero; try { uint buflen = 512; buffer = Marshal.AllocHGlobal((int)buflen); SetupDiGetDevicePropertyW( info, ref devdata, ref key, out proptype, buffer, buflen, out outsize, 0); byte[] lbuffer = new byte[outsize]; Marshal.Copy(buffer, lbuffer, 0, (int)outsize); int errcode = Marshal.GetLastWin32Error(); if (errcode == ERROR_ELEMENT_NOT_FOUND) return null; CheckError("SetupDiGetDeviceProperty", errcode); return Encoding.Unicode.GetString(lbuffer); } finally { if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); } } } 

Me he basado en la respuesta compatible con XP y la he mejorado un poco agregando una clase SafeDeviceInformationSetHandle y realizando una limpieza / refactorización general del código, y lo estoy agregando aquí para la posteridad:

 using System; using System.Text; using System.Security; using System.ComponentModel; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; public static class SetupApi { private const string SETUPAPI = "setupapi.dll"; private const int ERROR_INVALID_DATA = 13; private const int ERROR_INSUFFICIENT_BUFFER = 122; private class SafeDeviceInformationSetHandle : SafeHandleMinusOneIsInvalid { private SafeDeviceInformationSetHandle() : base(true) { } private SafeDeviceInformationSetHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) { SetHandle(preexistingHandle); } [SecurityCritical] protected override bool ReleaseHandle() { return SetupDiDestroyDeviceInfoList(handle); } } #region Enumerations [Flags] private enum DIGCF : uint { DEFAULT = 0x00000001, PRESENT = 0x00000002, ALLCLASSES = 0x00000004, PROFILE = 0x00000008, DEVICEINTERFACE = 0x00000010 } private enum SPDRP : uint { ///  /// DeviceDesc (R/W) ///  DEVICEDESC = 0x00000000, ///  /// HardwareID (R/W) ///  HARDWAREID = 0x00000001, ///  /// CompatibleIDs (R/W) ///  COMPATIBLEIDS = 0x00000002, ///  /// unused ///  UNUSED0 = 0x00000003, ///  /// Service (R/W) ///  SERVICE = 0x00000004, ///  /// unused ///  UNUSED1 = 0x00000005, ///  /// unused ///  UNUSED2 = 0x00000006, ///  /// Class (R--tied to ClassGUID) ///  CLASS = 0x00000007, ///  /// ClassGUID (R/W) ///  CLASSGUID = 0x00000008, ///  /// Driver (R/W) ///  DRIVER = 0x00000009, ///  /// ConfigFlags (R/W) ///  CONFIGFLAGS = 0x0000000A, ///  /// Mfg (R/W) ///  MFG = 0x0000000B, ///  /// FriendlyName (R/W) ///  FRIENDLYNAME = 0x0000000C, ///  /// LocationInformation (R/W) ///  LOCATION_INFORMATION = 0x0000000D, ///  /// PhysicalDeviceObjectName (R) ///  PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, ///  /// Capabilities (R) ///  CAPABILITIES = 0x0000000F, ///  /// UiNumber (R) ///  UI_NUMBER = 0x00000010, ///  /// UpperFilters (R/W) ///  UPPERFILTERS = 0x00000011, ///  /// LowerFilters (R/W) ///  LOWERFILTERS = 0x00000012, ///  /// BusTypeGUID (R) ///  BUSTYPEGUID = 0x00000013, ///  /// LegacyBusType (R) ///  LEGACYBUSTYPE = 0x00000014, ///  /// BusNumber (R) ///  BUSNUMBER = 0x00000015, ///  /// Enumerator Name (R) ///  ENUMERATOR_NAME = 0x00000016, ///  /// Security (R/W, binary form) ///  SECURITY = 0x00000017, ///  /// Security (W, SDS form) ///  SECURITY_SDS = 0x00000018, ///  /// Device Type (R/W) ///  DEVTYPE = 0x00000019, ///  /// Device is exclusive-access (R/W) ///  EXCLUSIVE = 0x0000001A, ///  /// Device Characteristics (R/W) ///  CHARACTERISTICS = 0x0000001B, ///  /// Device Address (R) ///  ADDRESS = 0x0000001C, ///  /// UiNumberDescFormat (R/W) ///  UI_NUMBER_DESC_FORMAT = 0X0000001D, ///  /// Device Power Data (R) ///  DEVICE_POWER_DATA = 0x0000001E, ///  /// Removal Policy (R) ///  REMOVAL_POLICY = 0x0000001F, ///  /// Hardware Removal Policy (R) ///  REMOVAL_POLICY_HW_DEFAULT = 0x00000020, ///  /// Removal Policy Override (RW) ///  REMOVAL_POLICY_OVERRIDE = 0x00000021, ///  /// Device Install State (R) ///  INSTALL_STATE = 0x00000022, ///  /// Device Location Paths (R) ///  LOCATION_PATHS = 0x00000023, } private enum DIF : uint { SELECTDEVICE = 0x00000001, INSTALLDEVICE = 0x00000002, ASSIGNRESOURCES = 0x00000003, PROPERTIES = 0x00000004, REMOVE = 0x00000005, FIRSTTIMESETUP = 0x00000006, FOUNDDEVICE = 0x00000007, SELECTCLASSDRIVERS = 0x00000008, VALIDATECLASSDRIVERS = 0x00000009, INSTALLCLASSDRIVERS = 0x0000000A, CALCDISKSPACE = 0x0000000B, DESTROYPRIVATEDATA = 0x0000000C, VALIDATEDRIVER = 0x0000000D, DETECT = 0x0000000F, INSTALLWIZARD = 0x00000010, DESTROYWIZARDDATA = 0x00000011, PROPERTYCHANGE = 0x00000012, ENABLECLASS = 0x00000013, DETECTVERIFY = 0x00000014, INSTALLDEVICEFILES = 0x00000015, UNREMOVE = 0x00000016, SELECTBESTCOMPATDRV = 0x00000017, ALLOW_INSTALL = 0x00000018, REGISTERDEVICE = 0x00000019, NEWDEVICEWIZARD_PRESELECT = 0x0000001A, NEWDEVICEWIZARD_SELECT = 0x0000001B, NEWDEVICEWIZARD_PREANALYZE = 0x0000001C, NEWDEVICEWIZARD_POSTANALYZE = 0x0000001D, NEWDEVICEWIZARD_FINISHINSTALL = 0x0000001E, UNUSED1 = 0x0000001F, INSTALLINTERFACES = 0x00000020, DETECTCANCEL = 0x00000021, REGISTER_COINSTALLERS = 0x00000022, ADDPROPERTYPAGE_ADVANCED = 0x00000023, ADDPROPERTYPAGE_BASIC = 0x00000024, RESERVED1 = 0x00000025, TROUBLESHOOTER = 0x00000026, POWERMESSAGEWAKE = 0x00000027, ADDREMOTEPROPERTYPAGE_ADVANCED = 0x00000028, UPDATEDRIVER_UI = 0x00000029, FINISHINSTALL_ACTION = 0x0000002A, RESERVED2 = 0x00000030, } private enum DICS : uint { ENABLE = 0x00000001, DISABLE = 0x00000002, PROPCHANGE = 0x00000003, START = 0x00000004, STOP = 0x00000005, } [Flags] private enum DICS_FLAG : uint { GLOBAL = 0x00000001, CONFIGSPECIFIC = 0x00000002, CONFIGGENERAL = 0x00000004, } #endregion #region Structures [StructLayout(LayoutKind.Sequential)] private struct SP_DEVINFO_DATA { public UInt32 cbSize; public Guid ClassGuid; public UInt32 DevInst; public IntPtr Reserved; } [StructLayout(LayoutKind.Sequential)] private struct SP_CLASSINSTALL_HEADER { public UInt32 cbSize; public DIF InstallFunction; } [StructLayout(LayoutKind.Sequential)] private struct SP_PROPCHANGE_PARAMS { public SP_CLASSINSTALL_HEADER ClassInstallHeader; public DICS StateChange; public DICS_FLAG Scope; public UInt32 HwProfile; } #endregion #region P/Invoke Functions [DllImport(SETUPAPI, SetLastError = true, CharSet = CharSet.Unicode)] private static extern SafeDeviceInformationSetHandle SetupDiGetClassDevs( [In] ref Guid ClassGuid, [In] string Enumerator, IntPtr hwndParent, DIGCF Flags ); [DllImport(SETUPAPI, SetLastError = true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [DllImport(SETUPAPI, SetLastError = true)] private static extern bool SetupDiEnumDeviceInfo( SafeDeviceInformationSetHandle DeviceInfoSet, UInt32 MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData ); [DllImport(SETUPAPI, SetLastError = true)] private static extern bool SetupDiSetClassInstallParams( SafeDeviceInformationSetHandle DeviceInfoSet, [In] ref SP_DEVINFO_DATA deviceInfoData, [In] ref SP_PROPCHANGE_PARAMS classInstallParams, UInt32 ClassInstallParamsSize ); [DllImport(SETUPAPI, SetLastError = true)] private static extern bool SetupDiChangeState( SafeDeviceInformationSetHandle DeviceInfoSet, [In, Out] ref SP_DEVINFO_DATA DeviceInfoData ); [DllImport(SETUPAPI, SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool SetupDiGetDeviceRegistryProperty( SafeDeviceInformationSetHandle DeviceInfoSet, [In] ref SP_DEVINFO_DATA DeviceInfoData, SPDRP Property, out RegistryValueKind PropertyRegDataType, [Out] byte[] PropertyBuffer, UInt32 PropertyBufferSize, out UInt32 RequiredSize ); #endregion private static void CheckWin32CallSuccess(bool success) { if (!success) { throw new Win32Exception(); } } private static string GetStringPropertyForDevice(SafeDeviceInformationSetHandle infoSet, ref SP_DEVINFO_DATA devInfo, SPDRP property) { RegistryValueKind regType; UInt32 requiredSize; if (!SetupDiGetDeviceRegistryProperty(infoSet, ref devInfo, property, out regType, null, 0, out requiredSize)) { switch (Marshal.GetLastWin32Error()) { case ERROR_INSUFFICIENT_BUFFER: break; case ERROR_INVALID_DATA: return string.Empty; default: throw new Win32Exception(); } } byte[] propertyBuffer = new byte[requiredSize]; CheckWin32CallSuccess(SetupDiGetDeviceRegistryProperty(infoSet, ref devInfo, property, out regType, propertyBuffer, (uint)propertyBuffer.Length, out requiredSize)); return Encoding.Unicode.GetString(propertyBuffer); } public static void EnableDevice(Func hardwareIdFilter, bool enable) { Guid nullGuid = Guid.Empty; using (SafeDeviceInformationSetHandle infoSet = SetupDiGetClassDevs(ref nullGuid, null, IntPtr.Zero, DIGCF.ALLCLASSES)) { CheckWin32CallSuccess(!infoSet.IsInvalid); SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA(); devInfo.cbSize = (UInt32) Marshal.SizeOf(devInfo); for (uint index = 0; ; ++index) { CheckWin32CallSuccess(SetupDiEnumDeviceInfo(infoSet, index, ref devInfo)); string hardwareId = GetStringPropertyForDevice(infoSet, ref devInfo, SPDRP.HARDWAREID); if ((!string.IsNullOrEmpty(hardwareId)) && (hardwareIdFilter(hardwareId))) { break; } } SP_CLASSINSTALL_HEADER classinstallHeader = new SP_CLASSINSTALL_HEADER(); classinstallHeader.cbSize = (UInt32) Marshal.SizeOf(classinstallHeader); classinstallHeader.InstallFunction = DIF.PROPERTYCHANGE; SP_PROPCHANGE_PARAMS propchangeParams = new SP_PROPCHANGE_PARAMS { ClassInstallHeader = classinstallHeader, StateChange = enable ? DICS.ENABLE : DICS.DISABLE, Scope = DICS_FLAG.GLOBAL, HwProfile = 0, }; CheckWin32CallSuccess(SetupDiSetClassInstallParams(infoSet, ref devInfo, ref propchangeParams, (UInt32)Marshal.SizeOf(propchangeParams))); CheckWin32CallSuccess(SetupDiChangeState(infoSet, ref devInfo)); } } } 

Se puede hacer utilizando los métodos P / Invoke en la API de instalación de Windows. Las funciones de API han estado en Windows desde W2K. Las llamadas API pueden requerir derechos administrativos. A continuación se muestra un código aproximado para usar estas API para desactivar (y habilitar) los dispositivos en C #, que permiten invocar:

 DisableDevice( n => n.ToUpperInvariant().Contains("VID_3F20&PID_8A1D"), true); // true disables the device, false enables it 

Esto funciona en Windows 10 en Dell inspi 15.

Logré resolver este problema usando DevManView.exe (freeware):

  1. Descargue DevManView.exe y coloque el archivo .exe en algún lugar: http://www.nirsoft.net/utils/device_manager_view.html

  2. Vaya a su Administrador de dispositivo y busque el Nombre del dispositivo que desea habilitar / deshabilitar.

  3. En C #, crea e inicia un nuevo proceso para deshabilitar el dispositivo (usando el nombre del dispositivo que encontraste en el administrador del dispositivo).

     Process devManViewProc = new Process(); devManViewProc.StartInfo.FileName = @"\DevManView.exe"; devManViewProc.StartInfo.Arguments = "/disable \"\""; devManViewProc.Start(); devManViewProc.WaitForExit(); 
  4. Y habilítalo de nuevo.

     devManViewProc.StartInfo.Arguments = "/enable \"\""; devManViewProc.Start(); devManViewProc.WaitForExit();