代码之家  ›  专栏  ›  技术社区  ›  Cheetah

如何以编程方式禁用系统设备?

  •  9
  • Cheetah  · 技术社区  · 14 年前

    Hardware Helper Library for C# 在CodeProject上。

    但我需要一些能在XP、Vista和Windows 7(x86和x64操作系统)上工作的东西。。。 我链接的项目仅适用于XP和Vista x86…甚至在以管理员权限运行应用程序时也是如此。

    6 回复  |  直到 5 年前
        1
  •  30
  •   Frank Racis    13 年前

    看起来drf版本中有两件事给你带来了麻烦。您的x64问题是由SP\u DEVINFO\u数据的uint需要IntPtr引起的。第二个是SetupDiGetDevicePropertyW函数是Vista+,不会在XP上运行。

    这是一个修正了这两个问题的版本。我在XPx86和Win7X64上测试了x86和AnyCPU。

    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);
            }
        }
    
    }
    
        2
  •  9
  •   drf    13 年前

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

    第一个参数是传递硬件ID的筛选器。这将禁用或启用与提供的筛选器匹配的第一个设备。如果设备已处于目标状态,则不起作用。

    代码如下。

    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);
        }
    }
    }
    
        3
  •  1
  •   DoomMuffins    10 年前

    我已经构建了XP兼容的答案,并通过添加 SafeDeviceInformationSetHandle 初始化并执行一些常规代码清理/重构,并将其添加到此处以供后代使用:

    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));
            }
        }
    }
    
        4
  •  1
  •   Jannis Kappertz    7 年前

    1. 下载DevManView.exe并将.exe文件放在以下位置: http://www.nirsoft.net/utils/device_manager_view.html

    2. 在C#中,创建并启动一个用于禁用设备的新进程(使用在设备管理器中找到的设备名称)。

      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. 再次启用它。

      devManViewProc.StartInfo.Arguments = "/enable \"<name of the device>\"";
      devManViewProc.Start();
      devManViewProc.WaitForExit();
      
        5
  •  0
  •   Tunaki    8 年前

    它可以使用Windows安装API上的P/Invoke方法来完成。API函数自W2K以来一直在Windows中。API调用可能需要管理权限。下面是一些使用这些api禁用(以及启用)C#中允许调用的设备的粗略代码:

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

    这适用于Dell inspi 15上的Windows 10。

        6
  •  0
  •   Peter    6 年前

    使用以下代码:

    public class DevconHelper
    {
        private readonly ILogger logger;
        public DevconHelper(ILogger logger)
        {
            this.logger = logger;
        }
    
        readonly static string devconPath = @"devcon\" + (Environment.Is64BitOperatingSystem ? "x64" : "x86") + @"\devcon.exe";
        readonly static Regex parseHwidsOutput = new Regex(@"(?<id>[^\n]+)\n {4}Name: (?<name>[^\n]+)\n {4}Hardware IDs:\n(?<hwids>(?: {8}[^\n]+\n?)+)");
        readonly static Regex parseEnableDisableOutput = new Regex(@"(\d+) device\(s\) (are enabled|disabled)\.");
    
        public async Task<IEnumerable<Device>> GetDevicesAsync(string filterString = "*")
        {
            logger.Trace("GetDevicesAsync");
            using (var listDevicesProcess = Process.Start(new ProcessStartInfo(devconPath, "hwids " + filterString) { RedirectStandardOutput = true, UseShellExecute = false }))
            {
                var content = await listDevicesProcess.StandardOutput.ReadToEndAsync();
    
                var matches = parseHwidsOutput.Matches(content.Replace(Environment.NewLine, "\n")); //Regex is based on \n
                logger.Trace("GetDevicesAsync process output: {Content}, parsed {NumberOfMatches}, devconPath: {DevconPath}", content, matches.Count, devconPath);
                return matches.OfType<Match>().Select(match =>
                {
                    var id = match.Groups["id"].Value;
                    var name = match.Groups["name"].Value;
                    var hwids = match.Groups["hwids"].Value.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(line => line.Trim());
                    return new Device() { Id = id, Name = name, HardwareIds = hwids.ToArray() };
                });
            }
        }
    
        public async Task<bool> EnableAsync(Device device)
        {
            logger.Trace("EnableAsync");
            using (var disableProcess = Process.Start(new ProcessStartInfo(devconPath, "enable " + device.HardwareIds.First()) { RedirectStandardOutput = true, UseShellExecute = false }))
            {
                var content = await disableProcess.StandardOutput.ReadToEndAsync();
                var lastLine = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Last();
                logger.Trace("EnableAsync process output: {Content}, LastLine: {LastLine}", content, lastLine);
                return parseEnableDisableOutput.IsMatch(lastLine);
            }
        }
    
        public async Task<bool> DisableAsync(Device device)
        {
            logger.Trace("DisableAsync");
            using (var disableProcess = Process.Start(new ProcessStartInfo(devconPath, "disable " + device.HardwareIds.First()) { RedirectStandardOutput = true, UseShellExecute = false }))
            {
                var content = await disableProcess.StandardOutput.ReadToEndAsync();
                var lastLine = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Last();
                logger.Trace("DisableAsync process output: {Content}, LastLine: {LastLine}", content, lastLine);
                return parseEnableDisableOutput.IsMatch(lastLine);
            }
        }
    
        public class Device
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public string[] HardwareIds { get; set; }
        }
    }
    

    你就可以这样用了。

    var devices = await devconHelper.GetDevicesAsync();
    var device = devices.FirstOrDefault(x => x.Name == Settings.GPSDeviceName);
    if (device != null)
    {
        logger.Trace("Found the device!");
        logger.Info("Disabling the device!");
        if (await devconHelper.DisableAsync(device))
        {
            logger.Info("GPS device has been disabled!");
        }
        else
        {
            logger.Warn("Failed to disable the device!");
        }
        await Task.Delay(1000);
        logger.Info("Enabling device!");
        if (await devconHelper.EnableAsync(device))
        {
            logger.Info("Device has been enabled!");
        }
        else
        {
            logger.Fatal("Failed to enable the device!");
        }
    }
    else
    {
        logger.Warn("Could not find the device!");
    }
    

    这已经在windows 10和8.1上测试过了,可以正常工作!