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

前端之家收集整理的这篇文章主要介绍了c# – 如何以编程方式禁用系统设备?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在寻找方法来禁用C#.NET中的系统设备,给定PID& VID或设备名称.

搜索后,我在这里找到这个项目:http://www.codeproject.com/KB/cs/HardwareHelper.aspx

但是我需要一些可以在XP,Vista& Windows 7(x86和x64操作系统)…我链接的项目仅适用于XP和Vista x86 …即使运行具有管理员权限的应用程序.

有没有人知道可以在所有操作系统上运行的解决方案/库?

谢谢.

解决方法

看起来drf的这个版本有两件事给你带来麻烦.您的x64问题是由SP_DEVINFO_DATA引起的,其中有一个需要IntPtr的uint.第二个是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,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,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,propId,out proptype,buffer,buflen,ref outsize);
            byte[] lbuffer = new byte[outsize];
            Marshal.Copy(buffer,lbuffer,(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);
        }
    }

}

猜你在找的C#相关文章