Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Win32 API函数以编程方式启用/禁用设备_C#_.net_Windows_Winapi_Pinvoke - Fatal编程技术网

C# Win32 API函数以编程方式启用/禁用设备

C# Win32 API函数以编程方式启用/禁用设备,c#,.net,windows,winapi,pinvoke,C#,.net,Windows,Winapi,Pinvoke,我正在编写一个小型C#应用程序,在检测到另一个鼠标设备时禁用一个设备(我的笔记本电脑触摸板),如果没有检测到鼠标,则再次启用触摸板。我甚至无法在设备管理器中禁用touchpad(它在默认的鼠标类驱动程序上运行) 我正在进行设备驱动程序开发,所以我想也许我可以编写一个小的过滤器驱动程序,它只接受ioctl来启用和禁用向设备堆栈上传递鼠标事件消息,并通过原始PDO从用户模式获取消息。然而,有人建议我可以通过函数在用户模式下完成这项工作。这将非常好,因为这种原始PDO通信方法是一种PITA 我以前只使

我正在编写一个小型C#应用程序,在检测到另一个鼠标设备时禁用一个设备(我的笔记本电脑触摸板),如果没有检测到鼠标,则再次启用触摸板。我甚至无法在设备管理器中禁用touchpad(它在默认的鼠标类驱动程序上运行)

我正在进行设备驱动程序开发,所以我想也许我可以编写一个小的过滤器驱动程序,它只接受ioctl来启用和禁用向设备堆栈上传递鼠标事件消息,并通过原始PDO从用户模式获取消息。然而,有人建议我可以通过函数在用户模式下完成这项工作。这将非常好,因为这种原始PDO通信方法是一种PITA

我以前只使用过SetupDiGetClassDevs,而且有这么多,如果有人对Win32 API的这一部分有更多经验,可以快速告诉我应该调用什么来停止/禁用鼠标设备或其接口,或者如果框架的黑暗角落中有什么东西可以这样做(可能在WMI中?)


更新(2009年9月24日)我想出了如何使用过滤器驱动程序来实现这一点,并在网站上发布了我是如何做到的。我仍然想知道是否可以直接从Win32启用或禁用设备,如果可以,如何启用或禁用,因此我将保留这个问题。

一种方法可能是使用该层。这一层中似乎定义了一些与设备相关的类。

您可以使用SetupDi API从Win32(以及通过p/Invoke从C#)启用/禁用设备,但并非所有设备都可以通过这种方式“禁用”

试图从Win32(或WMI或调用SetupDi*函数系列的任何其他API)禁用touchpad时遇到的问题是,大多数带有touchpad(“PS/2兼容鼠标”)的笔记本电脑中的默认鼠标驱动程序不支持使用SetupDi API禁用。我怀疑这可能是因为使用PS/2连接器的实际旧鼠标不能在不冲洗硬件的情况下进行热分离

要验证无法禁用,请进入设备管理器并右键单击鼠标驱动程序。如果看到禁用选项,可以使用SetupDi禁用它。如果没有禁用选项,你就不走运了。。。欢迎来到IOCTL土地

如果您确实看到一个禁用选项,那么下面的代码(从我找到的一个VB示例移植到C#)应该允许您禁用并重新启用设备

以下是调用库的代码:

    public static void EnableMouse(bool enable)
    {
        // every type of device has a hard-coded GUID, this is the one for mice
        Guid mouseGuid = new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}");

        // get this from the properties dialog box of this device in Device Manager
        string instancePath = @"ACPI\PNP0F03\4&3688D3F&0";

        DeviceHelper.SetDeviceEnabled(mouseGuid, instancePath, enable);
    }
这是图书馆本身,改编自

使用系统;
使用系统文本;
使用System.Collections.Generic;
使用禁用设备;
使用System.Runtime.InteropServices;
使用系统组件模型;
使用Microsoft.Win32.SafeHandles;
使用系统安全;
使用System.Runtime.ConstrainedExecution;
使用制度管理;
命名空间禁用设备
{
[标志()]
内部枚举SetupDiGetClassDevsFlags
{
默认值=1,
当前=2,
所有类别=4,
外形=8,
DeviceInterface=(int)0x10
}
内部枚举函数
{
选择设备=1,
InstallDevice=2,
分配资源=3,
属性=4,
移除=5,
FirstTimeSetup=6,
FoundDevice=7,
选择ClassDrivers=8,
ValidateClassDrivers=9,
InstallClassDrivers=(int)0xa,
CalcDiskSpace=(int)0xb,
DestroyPrivateData=(int)0xc,
ValidateDriver=(int)0xd,
检测=(int)0xf,
InstallWizard=(int)0x10,
数据=(int)0x11,
PropertyChange=(int)0x12,
EnableClass=(int)0x13,
检测验证=(int)0x14,
InstallDeviceFiles=(int)0x15,
UnRemove=(int)0x16,
选择BestCompatDRV=(int)0x17,
AllowistAll=(int)0x18,
RegisterDevice=(int)0x19,
NewDeviceWizardPreSelect=(int)0x1a,
NewDeviceWizardSelect=(int)0x1b,
NewDeviceWizardPreAnalyze=(int)0x1c,
NewDeviceWizardPostAnalyze=(int)0x1d,
NewDeviceWizardFinishInstall=(int)0x1e,
未使用的1=(int)0x1f,
InstallInterfaces=(int)0x20,
检测取消=(int)0x21,
RegisterCoinstors=(int)0x22,
AddPropertyPageAdvanced=(int)0x23,
AddPropertyPageBasic=(int)0x24,
Reserved1=(int)0x25,
疑难解答=(int)0x26,
PowerMessageWake=(int)0x27,
AddRemotePropertyPageAdvanced=(int)0x28,
UpdateDriverUI=(int)0x29,
Reserved2=(int)0x30
}
内部枚举StateChangeAction
{
启用=1,
禁用=2,
PropChange=3,
开始=4,
停止=5
}
[标志()]
内部枚举作用域
{
全局=1,
ConfigSpecific=2,
ConfigGeneral=4
}
内部枚举设置错误
{
NoAssociatedClass=未选中((int)0xe0000200),
类不匹配=未选中((int)0xe0000201),
DuplicateFound=未选中((int)0xe0000202),
NoDriverSelected=unchecked((int)0xe0000203),
KeyDoesNotExist=未选中((int)0xe0000204),
InvalidDeviceName=未选中((int)0xe0000205),
InvalidClass=未选中((int)0xe0000206),
DeviceStalReadyExists=未选中((int)0xe0000207),
DeviceNotRegistered=未选中((int)0xe0000208),
InvalidRegProperty=未选中((int)0xe0000209),
NoInf=未选中((int)0xe000020a),
nosuchdevinst=未选中((int)0xe000020b),
CantLoadClassIcon=unchecked((int)0xe000020c),
InvalidClassInstaller=未选中((int)0xe000020d),
DiDoDefault=未选中((int)0xe000020e),
DiNoFileCopy=未选中((int)0xe000020f),
InvalidHwProfile=未选中((int)0xe0000210),
NodeDeviceSelected=未选中((int)0xe0000211),
DeviceInfo列表锁定=未选中((int)0xe0000212),
DevInfo数据锁定=未选中((int)0xe0000213),
迪巴德
using System;
using System.Text;
using System.Collections.Generic;
using DisableDevice;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Microsoft.Win32.SafeHandles;
using System.Security;
using System.Runtime.ConstrainedExecution;
using System.Management;

namespace DisableDevice
{

    [Flags()]
    internal enum SetupDiGetClassDevsFlags
    {
        Default = 1,
        Present = 2,
        AllClasses = 4,
        Profile = 8,
        DeviceInterface = (int)0x10
    }

    internal enum DiFunction
    {
        SelectDevice = 1,
        InstallDevice = 2,
        AssignResources = 3,
        Properties = 4,
        Remove = 5,
        FirstTimeSetup = 6,
        FoundDevice = 7,
        SelectClassDrivers = 8,
        ValidateClassDrivers = 9,
        InstallClassDrivers = (int)0xa,
        CalcDiskSpace = (int)0xb,
        DestroyPrivateData = (int)0xc,
        ValidateDriver = (int)0xd,
        Detect = (int)0xf,
        InstallWizard = (int)0x10,
        DestroyWizardData = (int)0x11,
        PropertyChange = (int)0x12,
        EnableClass = (int)0x13,
        DetectVerify = (int)0x14,
        InstallDeviceFiles = (int)0x15,
        UnRemove = (int)0x16,
        SelectBestCompatDrv = (int)0x17,
        AllowInstall = (int)0x18,
        RegisterDevice = (int)0x19,
        NewDeviceWizardPreSelect = (int)0x1a,
        NewDeviceWizardSelect = (int)0x1b,
        NewDeviceWizardPreAnalyze = (int)0x1c,
        NewDeviceWizardPostAnalyze = (int)0x1d,
        NewDeviceWizardFinishInstall = (int)0x1e,
        Unused1 = (int)0x1f,
        InstallInterfaces = (int)0x20,
        DetectCancel = (int)0x21,
        RegisterCoInstallers = (int)0x22,
        AddPropertyPageAdvanced = (int)0x23,
        AddPropertyPageBasic = (int)0x24,
        Reserved1 = (int)0x25,
        Troubleshooter = (int)0x26,
        PowerMessageWake = (int)0x27,
        AddRemotePropertyPageAdvanced = (int)0x28,
        UpdateDriverUI = (int)0x29,
        Reserved2 = (int)0x30
    }

    internal enum StateChangeAction
    {
        Enable = 1,
        Disable = 2,
        PropChange = 3,
        Start = 4,
        Stop = 5
    }

    [Flags()]
    internal enum Scopes
    {
        Global = 1,
        ConfigSpecific = 2,
        ConfigGeneral = 4
    }

    internal enum SetupApiError
    {
        NoAssociatedClass = unchecked((int)0xe0000200),
        ClassMismatch = unchecked((int)0xe0000201),
        DuplicateFound = unchecked((int)0xe0000202),
        NoDriverSelected = unchecked((int)0xe0000203),
        KeyDoesNotExist = unchecked((int)0xe0000204),
        InvalidDevinstName = unchecked((int)0xe0000205),
        InvalidClass = unchecked((int)0xe0000206),
        DevinstAlreadyExists = unchecked((int)0xe0000207),
        DevinfoNotRegistered = unchecked((int)0xe0000208),
        InvalidRegProperty = unchecked((int)0xe0000209),
        NoInf = unchecked((int)0xe000020a),
        NoSuchHDevinst = unchecked((int)0xe000020b),
        CantLoadClassIcon = unchecked((int)0xe000020c),
        InvalidClassInstaller = unchecked((int)0xe000020d),
        DiDoDefault = unchecked((int)0xe000020e),
        DiNoFileCopy = unchecked((int)0xe000020f),
        InvalidHwProfile = unchecked((int)0xe0000210),
        NoDeviceSelected = unchecked((int)0xe0000211),
        DevinfolistLocked = unchecked((int)0xe0000212),
        DevinfodataLocked = unchecked((int)0xe0000213),
        DiBadPath = unchecked((int)0xe0000214),
        NoClassInstallParams = unchecked((int)0xe0000215),
        FileQueueLocked = unchecked((int)0xe0000216),
        BadServiceInstallSect = unchecked((int)0xe0000217),
        NoClassDriverList = unchecked((int)0xe0000218),
        NoAssociatedService = unchecked((int)0xe0000219),
        NoDefaultDeviceInterface = unchecked((int)0xe000021a),
        DeviceInterfaceActive = unchecked((int)0xe000021b),
        DeviceInterfaceRemoved = unchecked((int)0xe000021c),
        BadInterfaceInstallSect = unchecked((int)0xe000021d),
        NoSuchInterfaceClass = unchecked((int)0xe000021e),
        InvalidReferenceString = unchecked((int)0xe000021f),
        InvalidMachineName = unchecked((int)0xe0000220),
        RemoteCommFailure = unchecked((int)0xe0000221),
        MachineUnavailable = unchecked((int)0xe0000222),
        NoConfigMgrServices = unchecked((int)0xe0000223),
        InvalidPropPageProvider = unchecked((int)0xe0000224),
        NoSuchDeviceInterface = unchecked((int)0xe0000225),
        DiPostProcessingRequired = unchecked((int)0xe0000226),
        InvalidCOInstaller = unchecked((int)0xe0000227),
        NoCompatDrivers = unchecked((int)0xe0000228),
        NoDeviceIcon = unchecked((int)0xe0000229),
        InvalidInfLogConfig = unchecked((int)0xe000022a),
        DiDontInstall = unchecked((int)0xe000022b),
        InvalidFilterDriver = unchecked((int)0xe000022c),
        NonWindowsNTDriver = unchecked((int)0xe000022d),
        NonWindowsDriver = unchecked((int)0xe000022e),
        NoCatalogForOemInf = unchecked((int)0xe000022f),
        DevInstallQueueNonNative = unchecked((int)0xe0000230),
        NotDisableable = unchecked((int)0xe0000231),
        CantRemoveDevinst = unchecked((int)0xe0000232),
        InvalidTarget = unchecked((int)0xe0000233),
        DriverNonNative = unchecked((int)0xe0000234),
        InWow64 = unchecked((int)0xe0000235),
        SetSystemRestorePoint = unchecked((int)0xe0000236),
        IncorrectlyCopiedInf = unchecked((int)0xe0000237),
        SceDisabled = unchecked((int)0xe0000238),
        UnknownException = unchecked((int)0xe0000239),
        PnpRegistryError = unchecked((int)0xe000023a),
        RemoteRequestUnsupported = unchecked((int)0xe000023b),
        NotAnInstalledOemInf = unchecked((int)0xe000023c),
        InfInUseByDevices = unchecked((int)0xe000023d),
        DiFunctionObsolete = unchecked((int)0xe000023e),
        NoAuthenticodeCatalog = unchecked((int)0xe000023f),
        AuthenticodeDisallowed = unchecked((int)0xe0000240),
        AuthenticodeTrustedPublisher = unchecked((int)0xe0000241),
        AuthenticodeTrustNotEstablished = unchecked((int)0xe0000242),
        AuthenticodePublisherNotTrusted = unchecked((int)0xe0000243),
        SignatureOSAttributeMismatch = unchecked((int)0xe0000244),
        OnlyValidateViaAuthenticode = unchecked((int)0xe0000245)
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct DeviceInfoData
    {
        public int Size;
        public Guid ClassGuid;
        public int DevInst;
        public IntPtr Reserved;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct PropertyChangeParameters
    {
        public int Size;
        // part of header. It's flattened out into 1 structure.
        public DiFunction DiFunction;
        public StateChangeAction StateChange;
        public Scopes Scope;
        public int HwProfile;
    }

    internal class NativeMethods
    {

        private const string setupapi = "setupapi.dll";

        private NativeMethods()
        {
        }

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiCallClassInstaller(DiFunction installFunction, SafeDeviceInfoSetHandle deviceInfoSet, [In()]
ref DeviceInfoData deviceInfoData);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiEnumDeviceInfo(SafeDeviceInfoSetHandle deviceInfoSet, int memberIndex, ref DeviceInfoData deviceInfoData);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern SafeDeviceInfoSetHandle SetupDiGetClassDevs([In()]
ref Guid classGuid, [MarshalAs(UnmanagedType.LPWStr)]
string enumerator, IntPtr hwndParent, SetupDiGetClassDevsFlags flags);

        /*
        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiGetDeviceInstanceId(SafeDeviceInfoSetHandle deviceInfoSet, [In()]
ref DeviceInfoData did, [MarshalAs(UnmanagedType.LPTStr)]
StringBuilder deviceInstanceId, int deviceInstanceIdSize, [Out()]
ref int requiredSize);
        */
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiGetDeviceInstanceId(
           IntPtr DeviceInfoSet,
           ref DeviceInfoData did,
           [MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId,
           int DeviceInstanceIdSize,
           out int RequiredSize
        );

        [SuppressUnmanagedCodeSecurity()]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);

        [DllImport(setupapi, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiSetClassInstallParams(SafeDeviceInfoSetHandle deviceInfoSet, [In()]
ref DeviceInfoData deviceInfoData, [In()]
ref PropertyChangeParameters classInstallParams, int classInstallParamsSize);

    }

    internal class SafeDeviceInfoSetHandle : SafeHandleZeroOrMinusOneIsInvalid
    {

        public SafeDeviceInfoSetHandle()
            : base(true)
        {
        }

        protected override bool ReleaseHandle()
        {
            return NativeMethods.SetupDiDestroyDeviceInfoList(this.handle);
        }

    }

    public sealed class DeviceHelper
    {

        private DeviceHelper()
        {
        }

        /// <summary>
        /// Enable or disable a device.
        /// </summary>
        /// <param name="classGuid">The class guid of the device. Available in the device manager.</param>
        /// <param name="instanceId">The device instance id of the device. Available in the device manager.</param>
        /// <param name="enable">True to enable, False to disable.</param>
        /// <remarks>Will throw an exception if the device is not Disableable.</remarks>
        public static void SetDeviceEnabled(Guid classGuid, string instanceId, bool enable)
        {
            SafeDeviceInfoSetHandle diSetHandle = null;
            try
            {
                // Get the handle to a device information set for all devices matching classGuid that are present on the 
                // system.
                diSetHandle = NativeMethods.SetupDiGetClassDevs(ref classGuid, null, IntPtr.Zero, SetupDiGetClassDevsFlags.Present);
                // Get the device information data for each matching device.
                DeviceInfoData[] diData = GetDeviceInfoData(diSetHandle);
                // Find the index of our instance. i.e. the touchpad mouse - I have 3 mice attached...
                int index = GetIndexOfInstance(diSetHandle, diData, instanceId);
                // Disable...
                EnableDevice(diSetHandle, diData[index], enable);
            }
            finally
            {
                if (diSetHandle != null)
                {
                    if (diSetHandle.IsClosed == false)
                    {
                        diSetHandle.Close();
                    }
                    diSetHandle.Dispose();
                }
            }
        }

        private static DeviceInfoData[] GetDeviceInfoData(SafeDeviceInfoSetHandle handle)
        {
            List<DeviceInfoData> data = new List<DeviceInfoData>();
            DeviceInfoData did = new DeviceInfoData();
            int didSize = Marshal.SizeOf(did);
            did.Size = didSize;
            int index = 0;
            while (NativeMethods.SetupDiEnumDeviceInfo(handle, index, ref did))
            {
                data.Add(did);
                index += 1;
                did = new DeviceInfoData();
                did.Size = didSize;
            }
            return data.ToArray();
        }

        // Find the index of the particular DeviceInfoData for the instanceId.
        private static int GetIndexOfInstance(SafeDeviceInfoSetHandle handle, DeviceInfoData[] diData, string instanceId)
        {
            const int ERROR_INSUFFICIENT_BUFFER = 122;
            for (int index = 0; index <= diData.Length - 1; index++)
            {
                StringBuilder sb = new StringBuilder(1);
                int requiredSize = 0;
                bool result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize);
                if (result == false && Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
                {
                    sb.Capacity = requiredSize;
                    result = NativeMethods.SetupDiGetDeviceInstanceId(handle.DangerousGetHandle(), ref diData[index], sb, sb.Capacity, out requiredSize);
                }
                if (result == false)
                    throw new Win32Exception();
                if (instanceId.Equals(sb.ToString()))
                {
                    return index;
                }
            }
            // not found
            return -1;
        }

        // enable/disable...
        private static void EnableDevice(SafeDeviceInfoSetHandle handle, DeviceInfoData diData, bool enable)
        {
            PropertyChangeParameters @params = new PropertyChangeParameters();
            // The size is just the size of the header, but we've flattened the structure.
            // The header comprises the first two fields, both integer.
            @params.Size = 8;
            @params.DiFunction = DiFunction.PropertyChange;
            @params.Scope = Scopes.Global;
            if (enable)
            {
                @params.StateChange = StateChangeAction.Enable;
            }
            else
            {
                @params.StateChange = StateChangeAction.Disable;
            }

            bool result = NativeMethods.SetupDiSetClassInstallParams(handle, ref diData, ref @params, Marshal.SizeOf(@params));
            if (result == false) throw new Win32Exception();
            result = NativeMethods.SetupDiCallClassInstaller(DiFunction.PropertyChange, handle, ref diData);
            if (result == false)
            {
                int err = Marshal.GetLastWin32Error();
                if (err == (int)SetupApiError.NotDisableable)
                    throw new ArgumentException("Device can't be disabled (programmatically or in Device Manager).");
                else if (err >= (int)SetupApiError.NoAssociatedClass && err <= (int)SetupApiError.OnlyValidateViaAuthenticode)
                    throw new Win32Exception("SetupAPI error: " + ((SetupApiError)err).ToString());
                else
                    throw new Win32Exception();
            }
        }
    }
}