Could not convert variant of type (Null) into type

2019-03-20 07:17发布

问题:

Do you know why the block of code bellow will negate the "Could not convert variant of type (Null) into type (OleStr)" on some computers, not all of them but 3 out of ten computers generate the error message.

function GetWMIstringSW(const WMIClass, WMIProperty:string): string;

const
  wbemFlagForwardOnly = $00000020;

var
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  LNode         : TTreeNode;
  LNode2        : TTreeNode;

begin
  Result:='';
  FWbemObjectSet:= FWMIService.ExecQuery(Format('Select %s from %s',[WMIProperty, WMIClass]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;

  while oEnum.Next(1, FWbemObject, iValue) = 0 do
    begin
      if not VarIsNull(FWbemObject.Properties_.Item(WMIProperty).Value) then
      Result:=FWbemObject.Properties_.Item(WMIProperty).Value;
      LNode := ClientForm.TreeView1.Items.AddChild(Node, Format('%s',[String(FWbemObject.Name)]));

      LNode2 := ClientForm.TreeView1.Items.AddChild(LNode, Format('%s',[String(FWbemObject.Version)]));
      FWbemObject:=Unassigned;
    end;

end;

The function is then executed at FormCreate:

GETWMIstringSW('Win32_Product','Name');

Thank you so much for your help.

回答1:

You code fails when the value of a WMI property returns null. You can fix this, checking if the property has a null value before to cast or convert to an string. For this task you can use the VarIsNull function or just use the VarToStr method to safely convert variants to strings like so.

 LNode := ClientForm.TreeView1.Items.AddChild(Node, 
              Format('%s',[VarToStr(FWbemObject.Name)]));
 LNode2 := ClientForm.TreeView1.Items.AddChild(LNode, 
              Format('%s',[VarToStr(FWbemObject.Version)]));


回答2:

To avoid the error message do

NullStrictConvert := false; // avoid NULL OLE conversion error



回答3:

Sometimes, the FWbemObject is not NULL but an exception is raise : "Can'nt convert an Array of Variant in OleStr "

As exemple : the BiosVersion (is an array) To solve it, try this :

for I := VarArrayLowBound(FWbemObject.BIOSVersion, 1) to VarArrayHighBound(FWbemObject.BIOSVersion, 1) do L.Add( VarToStr(FWbemObject.BIOSVersion[i]) );

Regards

Zerrouki



回答4:

If you want to null variants to be automatically converted to empty strings, 0 integers, or false booleans, set NullStrictConvert (unit System.Variants) to False.