10

Delphiプログラムのサーバーとクライアントを作成しようとしているので、アプリを保護し、すべてのユーザーが制御下にあることを確認するには、ハンドルを失わないように変更できない一意のキーを提供する必要があるため、HDDにする必要があると思いますシリアル番号 + BIOS SN ですが、BIOS はマザーボードのバッテリーを取り外すと変更される可能性があるため、動作しないことを覚えています。だから私が今選んだのはHDDの本当のシリアル番号です私はそれを取得するために以下のコードを試していますが、うまくいきませんでした

    unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,WbemScripting_TLB,ActiveX;

type
  TForm4 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var  // These are all needed for the WMI querying process
  Locator:  ISWbemLocator;
  Services: ISWbemServices;
  SObject:  ISWbemObject;
  ObjSet:   ISWbemObjectSet;
  SProp:    ISWbemProperty;
  Enum:     IEnumVariant;
  Value:    Cardinal;
  TempObj:  OleVariant;
  SN: string;
begin
  try
  Locator := CoSWbemLocator.Create;  // Create the Location object
  // Connect to the WMI service, with the root\cimv2 namespace
   Services :=  Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
  ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
    wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
  Enum :=  (ObjSet._NewEnum) as IEnumVariant;
  while (Enum.Next(1, TempObj, Value) = S_OK) do
  begin
    SObject := IUnknown(tempObj) as ISWBemObject;
    SProp := SObject.Properties_.Item(wmiProperty, 0);
    if VarIsNull(SProp.Get_Value) then
      result := ''
    else
    begin
      SN := SProp.Get_Value;
      result :=  SN;
    end;
  end;
  except // Trap any exceptions (Not having WMI installed will cause one!)
   on exception do
    result := '';
   end;
end;

procedure TForm4.Button1Click(Sender: TObject);
var
x:string;
Y:string;

begin


    X:=GetWMIstring('','Win32_BIOS','SerialNumber');
    Y:=GetWMIstring('','Win32_DiskDrive"','SerialNumber')     ;

    ShowMessage(x+';'+y);
end;

end.

*だから、私のコードを修正するか、別のアイデアを教えてください。よろしくお願いします*

4

2 に答える 2

24

WMI クラス名で二重引用符を渡しているため、コードが機能していません。

このコードを変更

GetWMIstring('','Win32_DiskDrive"','SerialNumber');

これに

GetWMIstring('','Win32_DiskDrive','SerialNumber');

ところで、この質問への回答の推奨事項に従えば、WMI 関数 (GetWMIstring) を大幅に改善できますHow can I improve the WMI performance using delphi?

WbemScripting_TLBこのサンプルを試してください (このコードは遅延バインディングを使用しており、ユニットは必要ありません)

  uses
      ActiveX,
      ComObj;

    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;

    function  GetWMIstring(const WMIClass, WMIProperty:string): string;
    const
      wbemFlagForwardOnly = $00000020;
    var
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
    begin;
      Result:='';
      FWbemObjectSet:= FWMIService.ExecQuery(Format('Select %s from %s',[WMIProperty, WMIClass]),'WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      if oEnum.Next(1, FWbemObject, iValue) = 0 then

  if not VarIsNull(FWbemObject.Properties_.Item(WMIProperty).Value) then

     Result:=FWbemObject.Properties_.Item(WMIProperty).Value;

    FWbemObject:=Unassigned;
    end;

    procedure TForm4.Button1Click(Sender: TObject);
    var
      x:string;
      Y:string;
    begin
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');

      X:=GetWMIstring('Win32_BIOS','SerialNumber');
      Y:=GetWMIstring('Win32_PhysicalMedia','SerialNumber');

      ShowMessage(x+';'+y);
    end;
于 2012-11-04T03:36:42.260 に答える