用Delphi通过SetupAPI.dll列举和停用硬件设备

前天弄的东西,通过SetupAPI.dll列举硬件设备,部分是改自MSDN自带的例子,自己加了显示设备类型名和图标.代码是我一个个加上去的有些乱.

{Setup.pas---从SetupAPI.h里转的一些函数和常量}unit SetupAPI;interfaceuses   Windows;const   DIGCF_PRESENT = $0002;   DIGCF_ALLCLASSES = $0004;   SPDRP_DEVICEDESC = 0;   DIF_PROPERTYCHANGE = 18;   DICS_ENABLE = 1;   DICS_FLAG_GLOBAL = 1;   DICS_DISABLE = 2;type   HDEVINFO = type Cardinal;   DI_FUNCTION = type Cardinal;   PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;   SP_DEVINFO_DATA = record     cbSize: DWORD;     ClassGuid: TGUID;     DevInst: DWORD;     Reserved: Longint;   end;   PSP_CLASSINSTALL_HEADER = ^SP_CLASSINSTALL_HEADER;   SP_CLASSINSTALL_HEADER = record     cbSize: DWORD;     InstallFunction: DI_FUNCTION; { (DIF code) }   end;   PSP_PROPCHANGE_PARAMS = ^SP_PROPCHANGE_PARAMS;   SP_PROPCHANGE_PARAMS = record     ClassInstallHeader: SP_CLASSINSTALL_HEADER;     StateChange: DWORD;     Scope: DWORD;     HwProfile: DWORD;   end;   PSP_CLASSIMAGELIST_DATA = ^SP_CLASSIMAGELIST_DATA;   SP_CLASSIMAGELIST_DATA = record     cbSize: DWORD;     ImageList: HWND;     Reserved: DWORD;   end;function SetupDiGetClassDevs(const ClassGuid: PGUID; Enumerator: PChar;   hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;   external 'Setupapi.dll' name 'SetupDiGetClassDevsA';function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD;   DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiEnumDeviceInfo';function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO;   DeviceInfoData: PSP_DEVINFO_DATA; Propertys: DWORD; PropertyRegDataType: PWORD;   PropertyBuffer: PByte; PropertyBufferSize: DWORD; RequiredSize: PWORD): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyA';function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiDestroyDeviceInfoList';function SetupDiClassNameFromGuid(ClassGuid: PGUID; ClassName: PChar;   ClassNameSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiClassNameFromGuidA';function SetupDiSetClassInstallParams(DeviceInfoSet: HDEVINFO ;   DeviceInfoData: PSP_DEVINFO_DATA; ClassInstallParams: PSP_CLASSINSTALL_HEADER;   ClassInstallParamsSize: DWORD): BOOL stdcall;   external 'Setupapi.dll' name 'SetupDiSetClassInstallParamsA';function SetupDiCallClassInstaller(InstallFunction: DI_FUNCTION;   DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiCallClassInstaller';function SetupDiGetClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA): BOOL;   stdcall; external 'Setupapi.dll' name 'SetupDiGetClassImageList';function SetupDiDestroyClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA):   BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiDestroyClassImageList';function SetupDiGetClassImageIndex(ClassImageListData: PSP_CLASSIMAGELIST_DATA;   ClassGuid: PGUID; ImageIndex: PINT): BOOL; stdcall;   external 'Setupapi.dll' name 'SetupDiGetClassImageIndex';implementationend.{ untMain.pas主窗体单元,Uses部分引用上面的pas,再加1个BUTTON;1个TListView;1个TImageList,定义看代码 }unit untMain;interfaceuses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, SetupAPI, StdCtrls, ComCtrls, ImgList;type   TForm1 = class(TForm)     lv1: TListView;     btn1: TButton;     il1: TImageList;     procedure btn1Click(Sender: TObject);   private     function GetDeviceClassName(aGUID: TGUID): string;     { Private declarations }   public     { Public declarations }   end;var   Form1: TForm1;   ClassImageListData: SP_CLASSIMAGELIST_DATA; {设备类型图标结构,全局变量,退出时释放.}implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);var   hDevInfo: Cardinal;   DeviceInfoData: SP_DEVINFO_DATA; {设备信息结构}   i: Integer;   DataT, Buffersize: DWORD;   Buffer: PAnsiChar;   List: TListItem;   index: Integer;begin   { 获取设备信息句柄 }   lv1.Items.BeginUpdate;   DriverInfoData.cbSize := SizeOf(SP_DRVINFO_DATA_A);   hDevInfo := SetupDiGetClassDevs(nil, 0, 0,     DIGCF_PRESENT or DIGCF_ALLCLASSES);   if hDevInfo = INVALID_HANDLE_VALUE then Exit;   { 设备图标数据结构 }   ClassImageListData.cbSize := SizeOf(SP_CLASSIMAGELIST_DATA);   { 获取设备图标数据 }   if SetupDiGetClassImageList(@ClassImageListData) then   begin     { 赋句柄给ImageList }     il1.Handle := ClassImageListData.ImageList;     { TreeView图标指定到ImageList }     lv1.SmallImages := il1;   end;   i := 0;   Buffersize := 256;   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);   GetMem(Buffer, Buffersize);   { 枚举设备信息 }   while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do   begin     { 获取设备信息包括GUID和名称 }    SetupDiGetDeviceRegistryProperty(hDevInfo, @DeviceInfoData,       SPDRP_DEVICEDESC, @DataT, PByte(Buffer), Buffersize, nil);     Inc(i);     List := lv1.Items.Add;     { 获取制定GUID(设备类型)的图标索引 }     if SetupDiGetClassImageIndex(@ClassImageListData,       @DeviceInfoData.ClassGuid, @index) then       { 制定显示图标 }       List.ImageIndex := index;     { 通过GUID获取设备类型(Class) }     List.Caption := GetDeviceClassName(DeviceInfoData.ClassGuid);     { 转换GUID到字符串 }     List.SubItems.Add(GUIDToString(DeviceInfoData.ClassGuid));     { 显示设备名称 }     List.SubItems.Add(Buffer);     { 设备状态 }     if IsDisableable(i ,hDevInfo) then       List.SubItems.Add('True')     else       List.SubItems.Add('False');   end;   if Buffer <> nil then FreeMem(Buffer);   if (GetLastError() <> NO_ERROR) and     (GetLastError() <> ERROR_NO_MORE_ITEMS) then     Exit;   { 释放 DeviceInfoData, hDevInfo }   SetupDiDestroyDeviceInfoList(hDevInfo);   lv1.Items.EndUpdate;end;{最后在退出程序时释放 SetupDiDestroyClassImageList(@ClassImageListData); }{ 获取设备类型 }function TForm1.GetDeviceClassName(aGUID: TGUID): string;var   ClassName: PChar;   ClassNameSize: DWORD;begin   ClassNameSize := 0;   GetMem(ClassName, ClassNameSize);   { 利用GUID返回设备类型名 }   while not SetupDiClassNameFromGuid(@aGUID, ClassName, ClassNameSize,     @ClassNameSize) do   begin     if GetLastError() = ERROR_INSUFFICIENT_BUFFER then     begin       if ClassName <> nil then FreeMem(ClassName);       GetMem(ClassName, ClassNameSize);     end else       Break;   end;   Result := ClassName;   if ClassName <> nil then FreeMem(ClassName);end;end.{设备禁用的代码,是从网上改些一个C++代码的,还没来得及加注解,先看着,以后加.}function ChangeDeviceState(hDevInfo: HDEVINFO; NewStatus: DWORD;   SelectedItem: DWORD): Boolean;var   PropChangeParams: SP_PROPCHANGE_PARAMS;   DeviceInfoData: SP_DEVINFO_DATA;begin   Result := False;   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);   if not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, @DeviceInfoData) then Exit;   // Set the PropChangeParams structure.   PropChangeParams.ClassInstallHeader.cbSize := SizeOf(SP_CLASSINSTALL_HEADER);   PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;   PropChangeParams.Scope := DICS_FLAG_GLOBAL;   PropChangeParams.StateChange := NewStatus;   if not SetupDiSetClassInstallParams(hDevInfo, @DeviceInfoData,     PSP_CLASSINSTALL_HEADER(@PropChangeParams), SizeOf(PropChangeParams)) then     Exit;   // Call the ClassInstaller and perform the change.   if not SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo,     @DeviceInfoData) then     Exit;   Result := True;end;function ControlDisk(nStatus, nIndex: Integer): Boolean;var   Guid: TGUID ;   GUIDString: string;   hDevInfo: Cardinal;   i: DWORD;   DeviceInfoData: SP_DEVINFO_DATA;begin   Result := False;   if (nStatus = -1) then Exit;   ZeroMemory(@Guid, sizeof(TGUID));   case nIndex of     0: // 0 代表软驱       GUIDString := '{4D36E980-E325-11CE-BFC1-08002BE10318}';     1: // 1 代表光驱       GUIDString := '{4D36E965-E325-11CE-BFC1-08002BE10318}';     2: // 2 代表USB       GUIDString := '{36FC9E60-C465-11CF-8056-444553540000}';   end;   Guid := StringToGUID(GUIDString);   hDevInfo := SetupDiGetClassDevs(@Guid, nil, HWND(nil), DIGCF_PRESENT);   if (hDevInfo = INVALID_HANDLE_VALUE) then Exit;   ZeroMemory(@DeviceInfoData, SizeOf(SP_DEVINFO_DATA));   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);   i := 0;   while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do   begin     if nStatus   = 1 then       Result := ChangeDeviceState(hDevInfo, DICS_ENABLE, i)     else if nStatus = 2 then       Result := ChangeDeviceState(hDevInfo, DICS_DISABLE, i);     Inc(i);   end;   SetupDiDestroyDeviceInfoList(hDevInfo);end;{ 调用如下: 禁用光驱: if ControlDisk(DICS_DISABLE, 1) then ShowMessage('成功禁用!'); }{ 启用光驱: if ControlDisk(DICS_ENABLE, 1) then ShowMessage('启用成功!'); }{ 注意USB要调用2次 ControlDisk(DICS_ENABLE, 2)才能完成启用. }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索function
, 设备
, classname
, THEN
DWORD
delphi setupapi、ps停用图形硬件增强、delphi xe 硬件信息、delphi 获取硬件信息、delphi 硬件信息,以便于您获取更多的相关知识。

时间: 2025-01-27 00:09:18

用Delphi通过SetupAPI.dll列举和停用硬件设备的相关文章

Windows计算机中丢失SETUPAPI.dll

  Windows计算机中丢失SETUPAPI.dll的解决方法 Windows 2012 最近出现 计算机中丢失SETUPAPI.dll 的问题 查看日志未果,查看系统更新,好几个失败,没理! 是由于系统更新的原因:系统跟新失败,又没有回滚成功; 下载安装 2795944 更新,安装成功,重启,好了! 1 $>dir Windows8-RT-KB2795944-x64.msu 2 Volume in drive E has no label. 3 Volume Serial Number is

c#-C# 调用setupapi.dll里的方法出错

问题描述 C# 调用setupapi.dll里的方法出错 写的程序中调用了,如下代码 [DllImport("setupapi.dll", SetLastError = true)] public static extern bool SetupDiEnumDeviceInfo(IntPtr lpInfoSet, UInt32 dwIndex, SP_DEVINFO_DATA devInfoData); 可是不知为什么,这段代码在我的笔记本上测试有问题,产生不了正常结果.我的笔记本是W

delphi调用c++ dll参数char* 的问题

问题描述 delphi调用c++ dll参数char* 的问题 我有一个c作的dll 具体说明如下 1.文件解密接口函数及参数说明: int stdcall DecodeFile(char* InFile, //要解密的文件 char* Key, //解密的密钥 char* OutFile, //解密后的文件,在解密路径下的同名XML文件 char* Info); //提示信息函数返回 0 成功,非0失败. 2.动态调用实例: String jmfile = 要解密的文件路径; String k

c#调用delphi编写的dll文件报错,尝试读取或写入受保护的内存

问题描述 c#调用delphi编写的dll文件报错,尝试读取或写入受保护的内存 delphi函数原型 Procedure invoke(params :PChar; result : PChar) ; 解决方案 把这个delphi的原型改一下,改为 Function Pchar invoke(params :PChar) ; 再试试 解决方案二: Function invoke(params: PAnsiChar): PAnsiChar ;

.Net(C#) 调用Delphi 编写的DLL

问题描述 我通过动态加载动态库的方式调用Delphi编写的DLL的一个方法,执行时没问题,但是在调试时会出错:尝试在非托管DLL中执行托管代码步骤如下:通过WindowsAPI加载Delphi编写的DLL取得方法的指针将取得的方法转换为一个方法原型相同的委托实例A.(原型为:delegatevoidFuncation())A.Invoke();调试时就是这一步出错:尝试在非托管DLL中执行托管代码谁可以告诉我这个是什么原因? 解决方案 解决方案二:[DllImport("Delphidllnam

C#如何调用一个DELPHI写的dll

问题描述 兄弟们我有个问题请教一下:我用C#调用一个DELPHI写的dll,dll中有integer,pchar,single数据类型,integer和single类型都能读出来就是读pchar类型有问题,这个函数是个读卡函数,调用会报这个错"对PInvoke函数"WindowsApplication1!WindowsApplication1.mz_读医保卡::Freadcard"的调用导致堆栈不对称.原因可能是托管的PInvoke签名与非托管的目标签名不匹配.请检查PInv

请教delphi做的dll,由TStream包装的OleVariant,c#中用什么类型访问比较合适

问题描述 delphi代码functionZip(varSource:OleVariant):OleVariant;stdcall;beginResult:=StreamToOleVariant(CompressStream(OleVariantToStream(Source)));end;.net代码[DllImport("zlib32.dll",EntryPoint="Zip")]publicstaticexternobjectZCompress(objecti

c#怎样才能调Delphi做的DLL

问题描述 例如:在Delphi中的导出函数为:functionLoad_SWDJ(h:Thandle):integer;stdcall;beginapplication.Handle:=h;frmDeath:=TfrmDeath.Create(nil);tryfrmDeath.ShowModal;finallyfrmDeath.Free;end;end; 解决方案 解决方案二:import["Delphi.dll"解决方案三:[DllImport("**.dll")

java调用delphi写的DLL报错误签名错

问题描述 如题,但并不是每次都报错,只是偶尔.函数参数我只有两个,都是字符串类型:Java这边我定义为string类型,delphi的dll里我定义为widestring类型错误显示为:错误签名AppName:javaw.exeAppVer:6.0.160.1ModName:adsloc32.dllModVer:5.60.0.0Offset:00030b00我写的delphidll里面调用了adsloc32.dll.补充:我用的开发工具是eclipse,delphi3写的DLL. 解决方案 解决