Имеется программа с привязкой к материнской плате и процессору, все нормально в целом работает.
Привязка выполняется на основе функции GetWMIString (код на Delphi 7 приведен ниже),
В целом все нормально работает на 99% компьютерах.
Но есть одна проблема, которая проявляется на 1% компьютеров и совсем непонятно, что с этим делать.
Выскакивает ошибка
could not convert variant of type Dispatch into type(String)
- причем выскакивает она в строке, которая в коде функции помечена соответствующим комментарием.
Что было проверено:
Пытался копать - проверил следующее:
ShowMessage(inttostr(VarType(colItem.Properties_.I tem(wmiProperty, 0)))) - выдет 9 - то есть тип проблемного выражения, которое не присваивается переменной result, varDispatch
Там точно не NULL.
Вместо VarIsNull(colItem.Properties_.Item(wmiProperty, 0)) пробовал еще VarIsClear(colItem.Properties_.Item(wmiProperty, 0)) - то же самое - попадает на 2-ю ветку.
Дальше куда копать - непонятно
Что интересно, функция GetWMIstring иногда работает (даже на этих проблемных 1% компьютерах) - например,
s1 := GetWMIstring('.', 'root\CIMV2', 'Win32_BaseBoard','Product') //работает
s2 := GetWMIstring('.', 'root\CIMV2', 'Win32_BaseBoard','Manufacturer') //работает
s3 := GetWMIstring('.', 'root\CIMV2', 'Win32_BaseBoard','SerialNumber') //НЕ РАБОТАЕТ
В чем может быть причина?
Код функции:
Код:
function GetWMIstring0(wmiHost, root, wmiClass, wmiProperty: string): string;
var
objWMIService: OLEVariant;
colItems: OLEVariant;
colItem: OLEVariant;
oEnum: IEnumvariant;
iValue: LongWord;
function GetWMIObject(const objectName: String): IDispatch;
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker)); //здесь ошибка
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;
begin
objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s',[wmiHost,root]));
colItems := objWMIService.ExecQuery(Format('SELECT * FROM %s',[wmiClass]),'WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
while oEnum.Next(1, colItem, iValue) = 0 do begin
if VarIsNull(colItem.Properties_.Item(wmiProperty, 0)) then
Result := 'NULL'
else begin
//при выполнении следующей команды будет ошибка "could not convert variant of type Dispatch into type(String)"
Result := colItem.Properties_.Item(wmiProperty, 0)
end
end;
end;