2010-11-04 5 views
9

Je suis à la recherche d'un moyen de désactiver un périphérique système (USB ou interne) dans C# .NET donné soit le VID & PID ou le nom du périphérique. Après la recherche, j'ai trouvé Hardware Helper Library for C# sur CodeProject.Comment désactiver un appareil système par programme?

Mais j'ai besoin de quelque chose qui fonctionnera sur XP, Vista & Windows 7 (systèmes d'exploitation x86 et x64) ... le projet que j'ai lié fonctionne uniquement avec XP et Vista x86 ... même lors de l'exécution de l'application avec les privilèges d'administrateur.

Est-ce que quelqu'un connaît une solution qui fonctionnerait sur tous les systèmes d'exploitation?

Répondre

23

On dirait qu'il y avait deux choses dans la version de drf qui vous donnaient des problèmes. Votre problème x64 a été causé par SP_DEVINFO_DATA ayant un uint où un IntPtr était nécessaire. La seconde est que la fonction SetupDiGetDevicePropertyW est Vista + et ne fonctionnera pas sous XP.

Voici une version corrigée de ces deux problèmes. J'ai testé comme x86 et AnyCPU sur XPx86 et 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<string, bool> 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); 
     } 
    } 

} 
+0

Merci - cela fonctionne parfaitement (je pense). – Cheetah

+0

+1 exemple de travail impressionnant! – BradleyDotNET

+0

Est-ce que SetupDiGetDeviceProperty ne fonctionne pas avec .NET? Je reçois toujours l'erreur 87, mais en C++ faire la même chose, avec les mêmes paramètres fonctionne très bien. Je pensais peut-être un problème de déclaration DLLImport, comme une différence étrange que j'ai vu était les paramètres de commande ont été poussés sur la pile était différente dans C++ .NET. Mais j'ai eu exactement la même déclaration pour l'importation que ce code ici (et essayé plusieurs réglages). – Malaise

8

Cela peut être fait en utilisant des méthodes P/Invoke sur l'API d'installation de Windows. Les fonctions API ont été dans Windows depuis W2K. Les appels d'API peuvent nécessiter des droits d'administration. Ci-dessous un code rugueux pour utiliser ces API pour désactiver (ainsi que permettre) des dispositifs en C#, qui permettent invoquait:

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

Le premier paramètre est un filtre qui est passé l'ID de matériel. Cela désactive ou active le premier périphérique correspondant au filtre fourni. Il n'y a aucun effet si le périphérique est déjà dans l'état cible.

Le code suit.

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<string, bool> 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); 
    } 
} 
} 
+0

Bien que cela fonctionne, je ne peux compiler pour 'Tout CPU' et doit compiler pour x86. Cela nécessite des privilèges d'administrateur. Merci, s'il n'y a pas de réponses qui contournent la chose 'Any CPU', je vais vous donner la prime. – Cheetah

+0

Salut drf, s'il vous plaît j'essaie d'utiliser ce code dans. NET 2.0, pouvez-vous m'aider à traduire la fonction 'Func', je suppose que cela signifie 'devicepath.Contains (vid)'? Est-ce correct? Merci –

+0

@Chibueze Le paramètre 'System.Func ' dans DisableDevice est un prédicat où le premier périphérique énuméré avec un nom correspondant au prédicat est désactivé. Si vous connaissez le nom du périphérique lorsque la méthode est appelée, le type de paramètre filter peut être refactorisé avec une chaîne (par exemple, la signature de la fonction devient «void DisableDevice (Func filter, bool disable = true)») le segment 'filter (devicepath)' est remplacé par 'devicepath.ToUpperInvariant() == filter.ToUpperInvariant()'. Dans .NET 2, vous pouvez également utiliser 'delegate (string)' à la place d'une fonction lambda pour le prédicat. – drf

1

J'ai construit sur la réponse XP compatible et amélioré un peu en ajoutant une classe SafeDeviceInformationSetHandle et effectuer un nettoyage/refactoring de code général, et je suis ajouter ici pour la postérité:

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 
    { 
     /// <summary> 
     /// DeviceDesc (R/W) 
     /// </summary> 
     DEVICEDESC = 0x00000000, 

     /// <summary> 
     /// HardwareID (R/W) 
     /// </summary> 
     HARDWAREID = 0x00000001, 

     /// <summary> 
     /// CompatibleIDs (R/W) 
     /// </summary> 
     COMPATIBLEIDS = 0x00000002, 

     /// <summary> 
     /// unused 
     /// </summary> 
     UNUSED0 = 0x00000003, 

     /// <summary> 
     /// Service (R/W) 
     /// </summary> 
     SERVICE = 0x00000004, 

     /// <summary> 
     /// unused 
     /// </summary> 
     UNUSED1 = 0x00000005, 

     /// <summary> 
     /// unused 
     /// </summary> 
     UNUSED2 = 0x00000006, 

     /// <summary> 
     /// Class (R--tied to ClassGUID) 
     /// </summary> 
     CLASS = 0x00000007, 

     /// <summary> 
     /// ClassGUID (R/W) 
     /// </summary> 
     CLASSGUID = 0x00000008, 

     /// <summary> 
     /// Driver (R/W) 
     /// </summary> 
     DRIVER = 0x00000009, 

     /// <summary> 
     /// ConfigFlags (R/W) 
     /// </summary> 
     CONFIGFLAGS = 0x0000000A, 

     /// <summary> 
     /// Mfg (R/W) 
     /// </summary> 
     MFG = 0x0000000B, 

     /// <summary> 
     /// FriendlyName (R/W) 
     /// </summary> 
     FRIENDLYNAME = 0x0000000C, 

     /// <summary> 
     /// LocationInformation (R/W) 
     /// </summary> 
     LOCATION_INFORMATION = 0x0000000D, 

     /// <summary> 
     /// PhysicalDeviceObjectName (R) 
     /// </summary> 
     PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, 

     /// <summary> 
     /// Capabilities (R) 
     /// </summary> 
     CAPABILITIES = 0x0000000F, 

     /// <summary> 
     /// UiNumber (R) 
     /// </summary> 
     UI_NUMBER = 0x00000010, 

     /// <summary> 
     /// UpperFilters (R/W) 
     /// </summary> 
     UPPERFILTERS = 0x00000011, 

     /// <summary> 
     /// LowerFilters (R/W) 
     /// </summary> 
     LOWERFILTERS = 0x00000012, 

     /// <summary> 
     /// BusTypeGUID (R) 
     /// </summary> 
     BUSTYPEGUID = 0x00000013, 

     /// <summary> 
     /// LegacyBusType (R) 
     /// </summary> 
     LEGACYBUSTYPE = 0x00000014, 

     /// <summary> 
     /// BusNumber (R) 
     /// </summary> 
     BUSNUMBER = 0x00000015, 

     /// <summary> 
     /// Enumerator Name (R) 
     /// </summary> 
     ENUMERATOR_NAME = 0x00000016, 

     /// <summary> 
     /// Security (R/W, binary form) 
     /// </summary> 
     SECURITY = 0x00000017, 

     /// <summary> 
     /// Security (W, SDS form) 
     /// </summary> 
     SECURITY_SDS = 0x00000018, 

     /// <summary> 
     /// Device Type (R/W) 
     /// </summary> 
     DEVTYPE = 0x00000019, 

     /// <summary> 
     /// Device is exclusive-access (R/W) 
     /// </summary> 
     EXCLUSIVE = 0x0000001A, 

     /// <summary> 
     /// Device Characteristics (R/W) 
     /// </summary> 
     CHARACTERISTICS = 0x0000001B, 

     /// <summary> 
     /// Device Address (R) 
     /// </summary> 
     ADDRESS = 0x0000001C, 

     /// <summary> 
     /// UiNumberDescFormat (R/W) 
     /// </summary> 
     UI_NUMBER_DESC_FORMAT = 0X0000001D, 

     /// <summary> 
     /// Device Power Data (R) 
     /// </summary> 
     DEVICE_POWER_DATA = 0x0000001E, 

     /// <summary> 
     /// Removal Policy (R) 
     /// </summary> 
     REMOVAL_POLICY = 0x0000001F, 

     /// <summary> 
     /// Hardware Removal Policy (R) 
     /// </summary> 
     REMOVAL_POLICY_HW_DEFAULT = 0x00000020, 

     /// <summary> 
     /// Removal Policy Override (RW) 
     /// </summary> 
     REMOVAL_POLICY_OVERRIDE = 0x00000021, 

     /// <summary> 
     /// Device Install State (R) 
     /// </summary> 
     INSTALL_STATE = 0x00000022, 

     /// <summary> 
     /// Device Location Paths (R) 
     /// </summary> 
     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<string, bool> 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)); 
     } 
    } 
} 
0

Cela peut être fait en utilisant des méthodes P/Invoke sur l'API d'installation de Windows. Les fonctions API ont été dans Windows depuis W2K. Les appels d'API peuvent nécessiter des droits d'administration. Ci-dessous un code rugueux pour utiliser ces API pour désactiver (ainsi que permettre) des dispositifs en C#, qui permettent d'invoquer:

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

Cela fonctionne sur Windows 10 sur Dell inspi 15.

0

J'ai réussi à résoudre ce problème en utilisant DevManView.exe (freeware):

  1. Télécharger DevManView.exe et mettre le fichier .exe quelque part: http://www.nirsoft.net/utils/device_manager_view.html

  2. Accédez à votre Gestionnaire de périphériques et recherchez le Nom de l'appareil que vous souhaitez activer/désactiver. En C#, créez et démarrez un nouveau processus de désactivation du périphérique (en utilisant le nom du périphérique que vous avez trouvé dans le gestionnaire de périphériques).

    Process devManViewProc = new Process(); 
    devManViewProc.StartInfo.FileName = @"<path to DevManView.exe>\DevManView.exe"; 
    devManViewProc.StartInfo.Arguments = "/disable \"<name of the device>\""; 
    devManViewProc.Start(); 
    devManViewProc.WaitForExit(); 
    
  3. Et activez-le à nouveau.

    devManViewProc.StartInfo.Arguments = "/enable \"<name of the device>\""; 
    devManViewProc.Start(); 
    devManViewProc.WaitForExit(); 
    
Questions connexes