672 lines
19 KiB
Plaintext
672 lines
19 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.WMI }
|
|
{ }
|
|
{ Copyright (C) 2022 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.WMI;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Classes, System.SysUtils, Winapi.Windows,
|
|
Tocsg.Thread, EM.WbemScripting_TLB;
|
|
|
|
const
|
|
WMI_ROOT_OBJECT = 'root\cimv2';
|
|
KBYTE = Sizeof(Byte) shl 10;
|
|
MBYTE = KBYTE shl 10;
|
|
GBYTE = MBYTE shl 10;
|
|
|
|
WBEM_INFINITE = $FFFFFFFF;
|
|
WMI_SERVICE_NAME = 'Winmgmt';
|
|
|
|
WMI_EVENT_CREATE = 2084146945;
|
|
WMI_EVENT_MODIFY = 1531267689;
|
|
WMI_EVENT_DELETE = 2121895681;
|
|
|
|
type
|
|
TWMIEventKind = (wkUnknown, wkCreate, wkDelete, wkModify);
|
|
TWMINotifyEvent = procedure(Sender: TObject; WMIEventKind: TWMIEventKind;
|
|
ovEvent: OleVariant) of object;
|
|
TTgWmiEventThread = class(TTgThread)
|
|
private
|
|
bInit_,
|
|
bSync_: Boolean;
|
|
sWMIClass_: String;
|
|
ovEvent_: OleVariant;
|
|
WMIEventKind_: TWMIEventKind;
|
|
WbemLocator_: TSWbemLocator;
|
|
WbemEvent_: ISWbemEventSource;
|
|
evWMINotify_: TWMINotifyEvent;
|
|
procedure DoWMIEvent;
|
|
protected
|
|
procedure Execute; override;
|
|
public
|
|
Constructor Create(const sWMIClass: String; bSync: Boolean = true);
|
|
Destructor Destroy; override;
|
|
|
|
property OnWMINotify: TWMINotifyEvent write evWMINotify_;
|
|
end;
|
|
|
|
type
|
|
T2DimStrArray = array of array of string;
|
|
|
|
function WMI_GetPropertyString(WbemProperty: ISWbemProperty): String;
|
|
function WMI_GetSingleInstance(const sArg, sProp: String; var sResult: String): Boolean;
|
|
function WMI_GetSingleInstanceProperty(const sArg, sProp: String; var sResult: String): Boolean;
|
|
function WMI_GetInformationEx(const sCom, sNameSapce, sUser, sPass, sArg: String;
|
|
var wmiResults: T2DimStrArray; var nInstances: Integer): Boolean;
|
|
function WMI_GetPropertyIndex(wmiResults: T2DimStrArray; const sProp: String): Integer;
|
|
function WMI_GetPropertyData(wmiResults: T2DimStrArray; const sProp: String; nLine: Integer = 0): String;
|
|
function WMI_ConvWMIDateToDateTime(const sWmiDate: String; var nUTCOffset: Integer): TDateTime;
|
|
|
|
function WMI_GetTableInfo(const sTable, sField: String): String;
|
|
|
|
function WMI_GetOSInfo(const sField: String): String;
|
|
function WMI_GetOSInstallDateTime: TDateTime;
|
|
|
|
function WMI_GetCpuInfo: String;
|
|
|
|
function WMI_GetBaseboardInfo: String;
|
|
function WMI_GetMotherboardInfo: String;
|
|
|
|
function WMI_GetBiosInfo(const sField: String): String;
|
|
function WMI_GetBiosReleaseDateTime: TDateTime;
|
|
function WMI_GetBiosVersion: String;
|
|
function WMI_GetVideoController: String;
|
|
function WMI_GetNetworkTotalTraffic: LONGLONG;
|
|
function WMI_GetMemory: LONGLONG;
|
|
function WMI_GetMonitor: String;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Exception, Tocsg.Hash, Tocsg.Service, Tocsg.Safe, Tocsg.Trace,
|
|
Winapi.ActiveX, System.Win.ComObj, System.Variants, Tocsg.Strings;
|
|
|
|
{ TTgWmiEventThread }
|
|
|
|
Constructor TTgWmiEventThread.Create(const sWMIClass: String; bSync: Boolean = true);
|
|
begin
|
|
Inherited Create;
|
|
bSync_ := bSync;
|
|
sWMIClass_ := QuotedStr(sWMIClass);
|
|
WbemLocator_ := nil;
|
|
ovEvent_ := 0;
|
|
WbemEvent_ := nil;
|
|
evWMINotify_ := nil;
|
|
end;
|
|
|
|
Destructor TTgWmiEventThread.Destroy;
|
|
begin
|
|
evWMINotify_ := nil;
|
|
FreeAndNil(WbemLocator_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TTgWmiEventThread.DoWMIEvent;
|
|
begin
|
|
if Assigned(evWMINotify_) then
|
|
evWMINotify_(Self, WMIEventKind_, ovEvent_);
|
|
end;
|
|
|
|
procedure TTgWmiEventThread.Execute;
|
|
var
|
|
nReTryCnt: Integer;
|
|
|
|
function InitWMI: Boolean;
|
|
var
|
|
WbemServices: ISWbemServices;
|
|
sQuery: String;
|
|
begin
|
|
Result := false;
|
|
nLastError_ := 0;
|
|
|
|
// 알수없는 이유로... Create()에서 생성 안될거 생각해서 이렇게 변경
|
|
if WbemLocator_ = nil then
|
|
try
|
|
WbemLocator_ := TSWbemLocator.Create(nil);
|
|
WbemServices := WbemLocator_.ConnectServer('', WMI_ROOT_OBJECT, '', '', '', '', 0, nil)
|
|
except
|
|
WbemLocator_ := nil;
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
if WbemServices = nil then
|
|
begin
|
|
nLastError_ := 1;
|
|
_Trace('WMI.ConnectServer() .. Fail, Error = %d', [GetLastError]);
|
|
exit;
|
|
end;
|
|
sQuery := Format('SELECT * FROM __InstanceOperationEvent WITHIN 1 ' +
|
|
'WHERE TargetInstance ISA %s', [sWMIClass_]);
|
|
|
|
WbemEvent_ := WbemServices.ExecNotificationQuery(sQuery,
|
|
'WQL',
|
|
wbemFlagForwardOnly or wbemFlagReturnImmediately,
|
|
nil);
|
|
if WbemEvent_ = nil then
|
|
begin
|
|
nLastError_ := 2;
|
|
_Trace('WMISvc.ExecNotificationQuery() .. Fail, Error = %d', [GetLastError]);
|
|
exit;
|
|
end;
|
|
Result := true;
|
|
except
|
|
on e: Exception do
|
|
begin
|
|
nLastError_ := 3;
|
|
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
nReTryCnt := 0;
|
|
|
|
CoInitialize(nil);
|
|
|
|
// 운영체제가 잠금 상태일 경우 실패할 수 있다. 성공할때까지 시도..
|
|
// 위 처럼 예외처리로 서비스 재실행을 이렇게 변경해봄
|
|
while not Terminated and not bWorkStop_ and not InitWMI do
|
|
begin
|
|
Inc(nReTryCnt);
|
|
|
|
if nRetryCnt > 30 then
|
|
begin
|
|
// 10분동안 시도해서 안되면 서비스 재시작 하도록 수정
|
|
nReTryCnt := 0;
|
|
|
|
_Trace('InitWMI() .. try 10 minute .. Class="%s"', [sWMIClass_]);
|
|
ServiceStop(WMI_SERVICE_NAME);
|
|
Sleep(30000);
|
|
ServiceStart(WMI_SERVICE_NAME);
|
|
Sleep(10000);
|
|
end;
|
|
|
|
Sleep(10000);
|
|
end;
|
|
|
|
// if InitWMI then
|
|
while not Terminated and not bWorkStop_ and Assigned(WbemEvent_) do
|
|
begin
|
|
try
|
|
ovEvent_ := WbemEvent_.NextEvent(5000{WBEM_INFINITE});
|
|
|
|
case ConvStrToHash(ovEvent_.Path_.class) of
|
|
WMI_EVENT_CREATE : WMIEventKind_ := wkCreate; // __InstanceCreationEvent
|
|
WMI_EVENT_MODIFY : WMIEventKind_ := wkModify; // __InstanceModificationEvent
|
|
WMI_EVENT_DELETE : WMIEventKind_ := wkDelete; // __InstanceDeletionEvent
|
|
else continue;
|
|
end;
|
|
if bSync_ then
|
|
Synchronize(DoWMIEvent)
|
|
else
|
|
DoWMIEvent;
|
|
except
|
|
// 이거 예외 찍게 하면 엄청 찍혀서.. 일단 막자
|
|
// on e: Exception do
|
|
// ESunkException.TraceException(Self, e);
|
|
end;
|
|
end;
|
|
CoUninitialize;
|
|
end;
|
|
|
|
{ Other }
|
|
|
|
function WMI_GetPropertyString(WbemProperty: ISWbemProperty): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
|
|
if VarIsNull(WbemProperty.Get_Value) then
|
|
Result := 'NULL'
|
|
else begin
|
|
case WbemProperty.CIMType of
|
|
wbemCimtypeSint8,
|
|
wbemCimtypeUint8,
|
|
wbemCimtypeSint16,
|
|
wbemCimtypeUint16,
|
|
wbemCimtypeSint32,
|
|
wbemCimtypeUint32,
|
|
wbemCimtypeSint64 :
|
|
begin
|
|
if VarIsArray(WbemProperty.Get_Value) then
|
|
begin
|
|
for i := 0 to VarArrayHighBound(WbemProperty.Get_Value, 1) do
|
|
begin
|
|
if i > 0 then
|
|
Result := Result + '|';
|
|
Result := Result + IntToStr(WbemProperty.Get_Value[i]);
|
|
end;
|
|
end else
|
|
Result := IntToStr(WbemProperty.Get_Value);
|
|
end;
|
|
wbemCimtypeReal32, wbemCimtypeReal64 : result := FloatToStr (WbemProperty.Get_Value);
|
|
wbemCimtypeBoolean : if WbemProperty.Get_Value then result := 'True' else result := 'False';
|
|
wbemCimtypeString,
|
|
wbemCimtypeUint64 :
|
|
begin
|
|
if VarIsArray(WbemProperty.Get_Value) then
|
|
begin
|
|
for i := 0 to VarArrayHighBound(WbemProperty.Get_Value, 1) do
|
|
begin
|
|
if i > 0 then
|
|
Result := Result + '|';
|
|
Result := Result + WbemProperty.Get_Value [i];
|
|
end;
|
|
end else
|
|
Result := WbemProperty.Get_Value;
|
|
end;
|
|
wbemCimtypeDatetime : Result := WbemProperty.Get_Value;
|
|
wbemCimtypeReference : Result := WbemProperty.Get_Value;
|
|
wbemCimtypeChar16 : Result := '<16-bit character>';
|
|
wbemCimtypeObject : Result := '<CIM Object>';
|
|
end ;
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetSingleInstance(const sArg, sProp: String; var sResult: String): Boolean;
|
|
var
|
|
WbemLocator: TSWbemLocator;
|
|
WbemServices: ISWbemServices;
|
|
WbemObject: ISWbemObject;
|
|
WbemProperty: ISWbemProperty;
|
|
begin
|
|
Result := false;
|
|
|
|
sResult := '';
|
|
Guard(WbemLocator, TSWbemLocator.Create(nil));
|
|
try
|
|
WbemServices := WbemLocator.ConnectServer('', WMI_ROOT_OBJECT, '', '',
|
|
'', '', 0, nil);
|
|
WbemObject := WbemServices.Get(sArg, 0, nil);
|
|
WbemProperty := WbemObject.Properties_.Item(sProp, 0);
|
|
|
|
if WbemProperty.Name <> sProp then
|
|
exit;
|
|
|
|
sResult := WMI_GetPropertyString(WbemProperty);
|
|
|
|
if sResult <> 'NULL' then
|
|
Result := true;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. WMI_GetSingleInstance()');
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetSingleInstanceProperty(const sArg, sProp: String; var sResult: String): Boolean;
|
|
var
|
|
WbemLocator: TSWbemLocator;
|
|
WbemServices: ISWbemServices;
|
|
WbemObjectSet: ISWbemObjectSet;
|
|
WbemObject: ISWbemObject;
|
|
WbemProperty: ISWbemProperty;
|
|
ovVar: OleVariant;
|
|
dwValue: DWORD;
|
|
enum: IEnumVariant;
|
|
sInfo: String;
|
|
begin
|
|
Result := false;
|
|
|
|
sResult := '';
|
|
VarClear(ovVar);
|
|
Guard(WbemLocator, TSWbemLocator.Create(nil));
|
|
try
|
|
WbemServices := WbemLocator.ConnectServer('', WMI_ROOT_OBJECT, '', '',
|
|
'', '', 0, nil);
|
|
WbemObjectSet := WbemServices.ExecQuery(sArg, 'WQL',
|
|
wbemFlagReturnImmediately, nil);
|
|
|
|
enum := (WbemObjectSet._NewEnum) as IEnumVariant;
|
|
while (enum.Next(1, ovVar, dwValue) = S_OK) do
|
|
begin
|
|
WbemObject := IUnknown(ovVar) as SWBemObject;
|
|
WbemProperty := WbemObject.Properties_.Item(sProp, 0);
|
|
if WbemProperty.Name = sProp then
|
|
begin
|
|
sInfo := WMI_GetPropertyString(WbemProperty);
|
|
if sInfo <> 'NULL' then
|
|
Result := true;
|
|
|
|
SumString(sResult, sInfo, ', ');
|
|
end;
|
|
VarClear(ovVar);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(E, 'Fail .. WMI_GetSingleInstanceProperty()');
|
|
VarClear(ovVar);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetInformationEx(const sCom, sNameSapce, sUser, sPass, sArg: String;
|
|
var wmiResults: T2DimStrArray; var nInstances: Integer): Boolean;
|
|
var
|
|
WbemLocator: TSWbemLocator;
|
|
WbemServices: ISWbemServices;
|
|
WbemObjectSet: ISWbemObjectSet;
|
|
WbemObject: ISWbemObject;
|
|
WbemPropertySet: ISWbemPropertySet;
|
|
WbemProperty: ISWbemProperty;
|
|
propEnum, Enum: IEnumVariant;
|
|
ovVar1, ovVar2: OleVariant;
|
|
lwValue: DWORD;
|
|
sValue: String;
|
|
nInst, nRow, nCnt: Integer;
|
|
bDimmed: Boolean;
|
|
begin
|
|
Result := true;
|
|
|
|
nInstances := 0;
|
|
SetLength(wmiResults, 0, 0);
|
|
bDimmed := false;
|
|
VarClear(ovVar1);
|
|
VarClear(ovVar2);
|
|
Guard(WbemLocator, TSWbemLocator.Create(nil));
|
|
try
|
|
WbemServices := WbemLocator.ConnectServer(sCom,
|
|
sNameSapce,
|
|
sUser,
|
|
sPass,
|
|
'', '', 0, nil);
|
|
|
|
if Pos('SELECT', sArg) = 1 then
|
|
WbemObjectSet := WbemServices.ExecQuery(sArg, 'WQL', wbemFlagReturnImmediately, nil)
|
|
else
|
|
WbemObjectSet := WbemServices.InstancesOf(sArg, wbemFlagReturnImmediately or
|
|
wbemQueryFlagShallow, nil);
|
|
nInstances := WbemObjectSet.Count;
|
|
if nInstances = 0 then
|
|
exit;
|
|
|
|
// Replicate VBScript's "for each" construct
|
|
Enum := (WbemObjectSet._NewEnum) as IEnumVariant;
|
|
nInst := 0;
|
|
while(Enum.Next (1, ovVar1, lwValue) = S_OK) do
|
|
begin
|
|
WbemObject := IUnknown(ovVar1) as SWBemObject;
|
|
WbemPropertySet := WbemObject.Properties_;
|
|
nCnt := WbemPropertySet.Count;
|
|
if not bDimmed then
|
|
begin
|
|
SetLength(wmiResults, nInstances + 1, nCnt + 1);
|
|
wmiResults[0, 0] := 'Instance';
|
|
bDimmed := true;
|
|
end ;
|
|
propEnum := (WbemPropertySet._NewEnum) as IEnumVariant;
|
|
Inc(nInst);
|
|
nRow := 1;
|
|
wmiResults[nInst, 0] := IntToStr(nInst);
|
|
|
|
// Replicate VBScript's "for each" construct
|
|
while (propEnum.Next(1, ovVar2, lwValue) = S_OK) do
|
|
begin
|
|
WbemProperty := IUnknown(ovVar2) as SWBemProperty;
|
|
sValue := WMI_GetPropertyString(WbemProperty);
|
|
if nInst = 1 then wmiResults[0, nRow] := WbemProperty.Name;
|
|
wmiResults[nInst, nRow] := sValue;
|
|
Inc(nRow);
|
|
VarClear(ovVar2); // whomp them mem leaks
|
|
end;
|
|
end;
|
|
VarClear (ovVar1); // whomp them mem leaks
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(E, 'Fail .. WMI_GetInformationEx()');
|
|
VarClear (ovVar1);
|
|
VarClear (ovVar2);
|
|
Result := false;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetPropertyIndex(wmiResults: T2DimStrArray; const sProp: String): Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := 0;
|
|
for i := 1 to High(wmiResults[0]) do
|
|
begin
|
|
if wmiResults[0, i] = sProp then
|
|
begin
|
|
Result := i;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetPropertyData(wmiResults: T2DimStrArray; const sProp: String; nLine: Integer = 0): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
if (Length(wmiResults)-1) < (nLine+1) then
|
|
exit;
|
|
i := WMI_GetPropertyIndex(wmiResults, sProp);
|
|
if i > 0 then Result := wmiResults[nLine+1, i];
|
|
end;
|
|
|
|
function WMI_ConvWMIDateToDateTime(const sWmiDate: String; var nUTCOffset: Integer): TDateTime;
|
|
Const
|
|
// 지정된 고정길이 25
|
|
LEN_WMI_DATETIME = 25;
|
|
|
|
// yyyymmddhhnnss.zzzzzzsUUU +60 means 60 mins of UTC time
|
|
// 20030709091030.686000+060
|
|
// 1234567890123456789012345
|
|
var
|
|
yy, mm, dd,
|
|
hh, nn, ss, zz: Integer;
|
|
dt: TDateTime;
|
|
|
|
function GetNum(nOffset, nLen: integer): Integer;
|
|
var
|
|
n: Integer;
|
|
begin
|
|
Val(Copy(sWmiDate, nOffset, nLen), Result, n);
|
|
end;
|
|
|
|
begin
|
|
Result := ERROR_SUCCESS;
|
|
nUTCOffset := 0;
|
|
|
|
if length(sWmiDate) <> LEN_WMI_DATETIME then
|
|
exit;
|
|
|
|
yy := GetNum(1, 4);
|
|
mm := GetNum(5, 2);
|
|
if (mm = 0) or (mm > 12) then
|
|
exit;
|
|
|
|
dd := GetNum(7, 2);
|
|
if (dd = 0) or (dd > 31) then
|
|
exit;
|
|
|
|
if not TryEncodeDate(yy, mm, dd, result) then // D6 and later
|
|
begin
|
|
Result := -1;
|
|
exit;
|
|
end;
|
|
|
|
hh := GetNum(9, 2);
|
|
nn := GetNum(11, 2);
|
|
ss := GetNum(13, 2);
|
|
zz := 0 ;
|
|
if Length(sWmiDate) >= 18 then
|
|
zz := GetNum(16, 3);
|
|
|
|
if not TryEncodeTime(hh, nn, ss, zz, dt) then
|
|
exit; // D6 and later
|
|
|
|
Result := Result + dt;
|
|
nUTCOffset := GetNum(22, 4);
|
|
end;
|
|
|
|
function WMI_GetTableInfo(const sTable, sField: String): String;
|
|
begin
|
|
try
|
|
if not WMI_GetSingleInstanceProperty
|
|
(
|
|
Format('SELECT %s FROM %s', [sField, sTable]), sField, Result
|
|
) then TTgTrace.T('WMI_GetTableInfo .. Fail!!, Table = %s, Field = %s', [sTable, sField]);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, Format('Fail .. WMI_GetTableInfo() .. Table=%s, Field=%s', [sTable, sField]));
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetOSInfo(const sField: String): String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_OperatingSystem', sField);
|
|
end;
|
|
|
|
function WMI_GetOSInstallDateTime: TDateTime;
|
|
var
|
|
sWMIDate: String;
|
|
nUTCOffset: Integer;
|
|
begin
|
|
if WMI_GetSingleInstanceProperty('SELECT InstallDate FROM Win32_Registry', 'InstallDate', sWMIDate) then
|
|
Result := WMI_ConvWMIDateToDateTime(sWMIDate, nUTCOffset)
|
|
else
|
|
TTgTrace.T('WMI_GetOSInstallDateTime .. Fail!!');
|
|
end;
|
|
|
|
function WMI_GetCpuInfo: String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_Processor', 'Name');
|
|
end;
|
|
|
|
function WMI_GetBaseboardInfo: String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_BaseBoard', 'Product');
|
|
end;
|
|
|
|
function WMI_GetMotherboardInfo: String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_MotherboardDevice', 'Name');
|
|
end;
|
|
|
|
function WMI_GetBiosInfo(const sField: String): String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_BIOS', sField);
|
|
end;
|
|
|
|
function WMI_GetBiosReleaseDateTime: TDateTime;
|
|
var
|
|
nUTCOffset: Integer;
|
|
begin
|
|
Result := WMI_ConvWMIDateToDateTime(WMI_GetBiosInfo('ReleaseDate'), nUTCOffset);
|
|
end;
|
|
|
|
function WMI_GetBiosVersion: String;
|
|
var
|
|
nVerCnt: Integer;
|
|
wmiResults: T2DimStrArray;
|
|
begin
|
|
Result := '';
|
|
if WMI_GetInformationEx('', WMI_ROOT_OBJECT, '', '', 'Win32_BIOS', wmiResults, nVerCnt) then
|
|
begin
|
|
if nVerCnt > 0 then
|
|
Result := Format('%s v%s.%s', [WMI_GetPropertyData(wmiResults, 'SMBIOSBIOSVersion'),
|
|
WMI_GetPropertyData(wmiResults, 'SMBIOSMajorVersion'),
|
|
WMI_GetPropertyData(wmiResults, 'SMBIOSMinorVersion')]);
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetVideoController: String;
|
|
begin
|
|
Result := WMI_GetTableInfo('Win32_VideoController', 'Name');
|
|
end;
|
|
|
|
function WMI_GetNetworkTotalTraffic: LONGLONG;
|
|
var
|
|
nVerCnt: Integer;
|
|
wmiResults: T2DimStrArray;
|
|
i: Integer;
|
|
begin
|
|
Result := -1;
|
|
if WMI_GetInformationEx('', WMI_ROOT_OBJECT, '', '', 'Win32_PerfFormattedData_Tcpip_NetworkInterface', wmiResults, nVerCnt) then
|
|
begin
|
|
Result := 0;
|
|
for i := 0 to nVerCnt - 1 do
|
|
Inc(Result, StrToInt64Def(WMI_GetPropertyData(wmiResults, 'BytesTotalPersec', i), 0));
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetMemory: LONGLONG;
|
|
begin
|
|
Result := StrToInt64Def(WMI_GetTableInfo('Win32_ComputerSystem', 'TotalPhysicalMemory'), 0);
|
|
end;
|
|
|
|
function VariantByteArrayToString(V: Variant): string;
|
|
var
|
|
i, LowIdx, HighIdx: Integer;
|
|
Ch: Integer;
|
|
begin
|
|
Result := '';
|
|
if VarIsArray(V) then
|
|
begin
|
|
LowIdx := VarArrayLowBound(V, 1);
|
|
HighIdx := VarArrayHighBound(V, 1);
|
|
for i := LowIdx to HighIdx do
|
|
begin
|
|
try
|
|
// Null이나 비정상 값 방지
|
|
Ch := VarAsType(VarArrayGet(V, [i]), varByte);
|
|
if Ch > 0 then
|
|
Result := Result + Chr(Ch);
|
|
except
|
|
// 오류 발생 시 무시
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function WMI_GetMonitor: String;
|
|
var
|
|
SWbemLocator, SWbemServices, SWbemObjectSet, Item: OLEVariant;
|
|
Enum: IEnumVariant;
|
|
Value: Cardinal;
|
|
V: Variant;
|
|
Manufacturer, ProductCode: string;
|
|
begin
|
|
Result := '';
|
|
try
|
|
SWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
|
|
SWbemServices := SWbemLocator.ConnectServer('.', 'root\WMI');
|
|
SWbemObjectSet := SWbemServices.ExecQuery('SELECT * FROM WmiMonitorID', 'WQL', 0);
|
|
Enum := IEnumVariant(IUnknown(SWbemObjectSet._NewEnum));
|
|
while Enum.Next(1, Item, Value) = 0 do
|
|
begin
|
|
// 제조사와 제품 코드는 byte 배열로 리턴됨
|
|
ProductCode := VariantByteArrayToString(Item.Properties_.Item('UserFriendlyName').Value);
|
|
if ProductCode <> '' then
|
|
begin
|
|
SumString(Result, ProductCode, ', ');
|
|
end else begin
|
|
Manufacturer := VariantByteArrayToString(Item.Properties_.Item('ManufacturerName').Value);
|
|
ProductCode := VariantByteArrayToString(Item.Properties_.Item('ProductCodeID').Value);
|
|
// SumString(Result, Format('Manufacturer: %s, Product Code: %s', [Manufacturer, ProductCode]), ', ');
|
|
SumString(Result, Manufacturer + ' ' + ProductCode, ', ');
|
|
end;
|
|
Item := Unassigned;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. WMI_GetMonitor()');
|
|
end;
|
|
end;
|
|
|
|
end.
|