前天弄的东西,通过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