gpt4 book ai didi

delphi - 如何正确检索电池序列号?

转载 作者:行者123 更新时间:2023-12-03 14:51:19 29 4
gpt4 key购买 nike

在 Delphi 7 中,我正在开发一个库,该库实现一个对象,该对象封装有关连接到系统的电池的信息。除了检索电池的序列号之外,它运行良好。

我用于此调用的代码如下:

function TBattery.GetSerialNumber(hbat: THandle): boolean;
var
bqi: TBatteryQueryInformation;
Serial: PWideChar;
SerialSize,
dwOut: DWORD;
begin
Result := False;

if hbat <> INVALID_HANDLE_VALUE then
begin
ZeroMemory(@bqi, SizeOf(bqi));
dwOut := 0;

bqi.BatteryTag := FBatteryTag;
bqi.InformationLevel := BatterySerialNumber;

SerialSize := 2048;
GetMem(Serial, SerialSize);
try
ZeroMemory(Serial, SerialSize);

Result := DeviceIoControl(hbat, IOCTL_BATTERY_QUERY_INFORMATION, @bqi,
SizeOf(bqi), Serial, SerialSize, @dwOut, nil);

if Result then
FSerialNumber := Serial;
finally
FreeMem(Serial, SerialSize);
end;
end;
end;

不幸的是,DeviceIoControl() 总是返回 False,如果我随后检查 GetLastError(),则会返回错误 87,“参数不正确。”

这没有多大意义,因为如果我简单地将 InformationLevelBatterySerialNumber 更改为 BatteryUniqueID,代码就可以正常工作,比如说。另外,我在 GetSerialNumber 之前的代码中的其他调用中使用了电池句柄 (hbat),它们都工作正常,我可以在这之后调用其他调用也失败了,所以这不是问题。

有什么想法吗?我真的很茫然。

最佳答案

该问题似乎与作为@dwOut 传递的dwOut 变量有关,该变量表示 DeviceIoControl 的 var lpBytesReturned 参数定义为

function DeviceIoControl(hDevice: THandle; dwIoControlCode: DWORD; lpInBuffer: Pointer;
nInBufferSize: DWORD; lpOutBuffer: Pointer; nOutBufferSize: DWORD;
var lpBytesReturned: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

因此将您的代码替换为

  Result := DeviceIoControl(hbat, IOCTL_BATTERY_QUERY_INFORMATION, @bqi,
SizeOf(bqi), Serial, SerialSize, dwOut, nil);

必须解决问题。

WinAPI

另请检查此 msdn 条目 Enumerating Battery Devices 翻译为 delphi 的代码这可以帮助您检测代码的任何其他问题。

uses
SetupApi,
Windows,
SysUtils;

type

BATTERY_QUERY_INFORMATION_LEVEL = (
BatteryInformation,
BatteryGranularityInformation,
BatteryTemperature,
BatteryEstimatedTime,
BatteryDeviceName,
BatteryManufactureDate,
BatteryManufactureName,
BatteryUniqueID,
BatterySerialNumber);
TBatteryQueryInformationLevel = BATTERY_QUERY_INFORMATION_LEVEL;

_BATTERY_QUERY_INFORMATION = record
BatteryTag: ULONG;
InformationLevel: BATTERY_QUERY_INFORMATION_LEVEL;
AtRate: Longint;
end;
BATTERY_QUERY_INFORMATION = _BATTERY_QUERY_INFORMATION;
PBATTERY_QUERY_INFORMATION = ^BATTERY_QUERY_INFORMATION;
TBatteryQueryInformation = BATTERY_QUERY_INFORMATION;


const
GUID_DEVCLASS_BATTERY:TGUID='{72631E54-78A4-11D0-BCF7-00AA00B7B32A}';
//DEFINE_GUID( GUID_DEVCLASS_BATTERY, 0x72631E54, 0x78A4, 0x11D0, 0xBC, 0xF7, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A );
METHOD_BUFFERED = 0;
FILE_DEVICE_BATTERY = $00000029;
FILE_READ_ACCESS = $0001; // for files and pipes

IOCTL_BATTERY_QUERY_TAG =
(FILE_DEVICE_BATTERY shl 16) or (FILE_READ_ACCESS shl 14) or ($10 shl 2) or (METHOD_BUFFERED);
IOCTL_BATTERY_QUERY_INFORMATION =
(FILE_DEVICE_BATTERY shl 16) or (FILE_READ_ACCESS shl 14) or ($11 shl 2) or (METHOD_BUFFERED);

function GetBatteryInfo(InformationLevel : BATTERY_QUERY_INFORMATION_LEVEL) : string;
var
cbRequired : DWORD;
hdev : HDEVINFO;
idev : Integer;
did : TSPDeviceInterfaceData;
pdidd : PSPDeviceInterfaceDetailData;
hBattery : THandle;
bqi : TBatteryQueryInformation;
dwWait, dwOut : DWORD;
lpOutBuffer: PWideChar;
begin
// enumerate the batteries
hdev := SetupDiGetClassDevs(@GUID_DEVCLASS_BATTERY, nil, 0, DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE);
if ( INVALID_HANDLE_VALUE <> THandle(hdev) ) then
begin
idev:=0;//first battery
ZeroMemory(@did, SizeOf(did));
did.cbSize := SizeOf(did);
if (SetupDiEnumDeviceInterfaces(hdev, nil, GUID_DEVCLASS_BATTERY, idev, did)) then
begin
try
cbRequired := 0;
SetupDiGetDeviceInterfaceDetail(hdev, @did, nil, 0, cbRequired, nil);
if (ERROR_INSUFFICIENT_BUFFER= GetLastError()) then
begin
pdidd:=AllocMem(cbRequired);
try
pdidd.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
if (SetupDiGetDeviceInterfaceDetail(hdev, @did, pdidd, cbRequired, cbRequired, nil)) then
begin
hBattery :=CreateFile(pdidd.DevicePath, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (INVALID_HANDLE_VALUE <> hBattery) then
begin
try
ZeroMemory(@bqi, SizeOf(bqi));
// With the tag, you can query the battery info.
dwWait := 0;
if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, @dwWait, sizeof(dwWait), @bqi.BatteryTag, sizeof(bqi.BatteryTag), dwOut, nil)) then
begin
lpOutBuffer:=AllocMem(MAX_PATH);
try
ZeroMemory(lpOutBuffer,MAX_PATH);
bqi.InformationLevel:=InformationLevel;
if DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, @bqi, SizeOf(BATTERY_QUERY_INFORMATION), lpOutBuffer, 255, dwOut,nil) then
Result:= WideCharToString(lpOutBuffer);
finally
FreeMem(lpOutBuffer);
end;
end;
finally
CloseHandle(hBattery)
end;
end;
end;
finally
FreeMem(pdidd);
end;
end;
finally
SetupDiDestroyDeviceInfoList(hdev);
end;
end;
end;
end;

begin
try
if not LoadsetupAPI then exit;
Writeln(GetBatteryInfo(BatterySerialNumber));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.

WMI

最后,请注意,您可以使用 WMI 检索相同的信息,在本例中使用 BatteryStaticData WMI 类

    {$APPTYPE CONSOLE}

uses
SysUtils,
ActiveX,
ComObj,
Variants;

// Battery Static Data

procedure GetBatteryStaticDataInfo;
const
WbemUser ='';
WbemPassword ='';
WbemComputer ='localhost';
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\WMI', WbemUser, WbemPassword);
FWbemObjectSet:= FWMIService.ExecQuery('SELECT SerialNumber FROM BatteryStaticData','WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
Writeln(Format('SerialNumber %s',[String(FWbemObject.SerialNumber)]));// String

Writeln('');
FWbemObject:=Unassigned;
end;
end;


begin
try
CoInitialize(nil);
try
GetBatteryStaticDataInfo;
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.

关于delphi - 如何正确检索电池序列号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10825711/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com