7

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、「パラメーターが正しくありません」で返されます。

InformationLevelを からBatterySerialNumberに変更するだけでコードが完全に機能するため、これはあまり意味がありませんBatteryUniqueIDhbatまた、以前のコードの他の呼び出しでバッテリーへのハンドル ( ) を使用したことがありますがGetSerialNumber、それらはすべて正常に動作し、これが失敗した後に他の呼び出しを行うこともできるので、それは問題ではありません。

何か案は?私は本当に途方に暮れています。

4

2 に答える 2

0

要約すると、コード@RRUZと私が投稿したものは、Windows7やその他のサードパーティアプリケーションで正常に機能します。WindowsXPではシリアル番号を取得するためには機能しません。また、WinXPおよび7で、まったく同じハードウェアにOSを基本インストールしてテストしたところ、同じ結果が得られました(WindowsXPではなくWindows7で成功しました)。

WinXPでは、のメンバーの値BatterySerialNumberはサポートされていないようですが、これはWindowsSDKドキュメントに直接記載されていません。無効なエントリはに対してエラー1()を返す必要があることが文書化されていますが、この場合は代わりに87(無効なパラメータに対して)を返します。これは、列挙内のその値が無効であるため、パラメーターが無効になるためだと思いますが、正確にはわかりません。IOCTL_BATTERY_QUERY_INFORMATIONInformationLevelERROR_INVALID_FUNCTIONGetLastError()

すべての人の助けに感謝します。特に@RRUZは、さらに上を行き来してくれました。

(余談ですが、バッテリーの一意のIDからシリアル番号を抽出し(メンバーBatteryUniqueIDとして使用InformationLevel)、一意のIDからメーカー名とデバイス名を削除できるようです。これはひどいハックですが、半ば実行可能な回避策です。 Windows XPの場合。)

于 2012-05-31T21:24:29.663 に答える