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