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

我正在寻找在给定PID和VID或设备名称的情况下在C#.NET中禁用系统设备(USB或内部)的方法。

搜索后,我在CodeProject上找到了用于C#的硬件助手库。

但是我需要在XP,Vista和Windows 7(x86和x64操作系统)上都可以使用的东西…

有谁知道可以在所有操作系统上使用的解决方案?

回答:

看起来drf版本中有两件事给您带来麻烦。您的x64问题是由SP_DEVINFO_DATA的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);

}

}

}

以上是 如何以编程方式禁用系统设备? 的全部内容, 来源链接: utcz.com/qa/424067.html

回到顶部