我正在寻找方法来禁用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);
- }
- }
- }