* * *

Author Topic: Passing Arguments to Procedure (WMI, FSWbemLocator.ConnectServer, 0x800706BA)  (Read 1241 times)

devers000

  • Newbie
  • Posts: 2
Hi All!
I'm trying to write application to automate remote information gathering.
I use Lazarus v. 1.6.4 (fpc 3.0.2) and wmi-delphi-code-creator v. 1.9.9.350
Here is the code:
Code: Pascal  [Select]
  1. program GetWMI_Info;
  2.  
  3. {$mode objfpc} {$H+}
  4.  
  5. uses
  6.   SysUtils,
  7.   ActiveX,
  8.   ComObj,
  9.   Variants;
  10.                
  11. procedure  GetWin32_BaseBoardInfo(WbemComputer, WbemUser, WbemPassword: string);
  12. const
  13.   wbemFlagForwardOnly = $00000020;
  14. var
  15.   FSWbemLocator : OLEVariant;
  16.   FWMIService   : OLEVariant;
  17.   FWbemObjectSet: OLEVariant;
  18.   FWbemObject   : OLEVariant;
  19.   oEnum         : IEnumvariant;
  20.   sValue        : string;
  21.   i             : LongWord;  
  22. begin;
  23.   i := 0;
  24.   FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  25.   FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  26.   FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_BaseBoard','WQL',wbemFlagForwardOnly);
  27.   oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  28.   while oEnum.Next(1, FWbemObject, i) = 0 do
  29.   begin
  30.     sValue:= FWbemObject.Properties_.Item('Manufacturer').Value;
  31.     Writeln(Format('Manufacturer    %s',[sValue]));
  32.     FWbemObject:=Unassigned;
  33.   end;
  34. end;
  35.  
  36. begin
  37.  try
  38.     GetWin32_BaseBoardInfo('PCNAME','user','password');
  39.  except
  40.     on E:EOleException do
  41.         Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));      
  42.         on E:Exception do
  43.         Writeln(E.Classname, ':', E.Message);
  44.  end;
  45.  Writeln('Press Enter to exit');
  46.  Readln;    
  47. end.

When I run application using this code I have the following error:
Code: Pascal  [Select]
  1. EOleException RPC server is unavailable.  800706BA

But if I change code like this:
Code: Pascal  [Select]
  1. FWMIService   := FSWbemLocator.ConnectServer('PCNAME', 'root\CIMV2', 'user', 'password');
Application works without error...
I think that passing arguments to procedure is wrong but I don't understand why...
Please, help to solve this problem. Any help is appreciated! Thanks

Thaddy

  • Hero Member
  • *****
  • Posts: 4803
Try
Code: Pascal  [Select]
  1. procedure  GetWin32_BaseBoardInfo(WbemComputer, WbemUser, WbemPassword: widestring);
WMI is a widestring API, so pass it widestring or unicodestring - which is a refcounted 16bit widestring -. sValue should also be widestring or unicodestring.

I see you have a console program. In that case you can change the mode to {$MODE DELPHIUNICODE} instead of objfpc. Then all strings are 16bit unicode by default.
Don't do this is in a Lazarus GUI app. There you should specify the strings as widestring or unicode string when calling a 16bit string API like WMI.

So my guess is that your console program works if you change it just a little:
Code: Pascal  [Select]
  1. program GetWMI_Info;
  2.  
  3. {$mode delphiunicode} {$H+}

wmi-delphi-code-creator is broken for current Lazarus versions because of the "enlightened" UTF8 string type.
Until Lazarus (and fpc rtl) supports UTF16 fully, you should specify a 16bit string type when doing
Windows API calls, or use mode delphiunicode for console apps like your example.
 
« Last Edit: March 13, 2017, 10:09:15 pm by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

devers000

  • Newbie
  • Posts: 2
Thank you, Thaddy:)
I develop GUI and you're right! I need to use WideString.
Now it's working like a charm! 8)

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3263
  • I like bugs.
Thank you, Thaddy:)
I develop GUI and you're right! I need to use WideString.
Actually you should use UnicodeString instead.
A nice bonus with the Lazarus UTF-8 system is that your code is compatible with Delphi at source level when using UnicodeString for the API calls despite the encoding differences.
Another thing to remember: you must assign string constants only to type "string" variables which is also Delphi compatible.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus