TWAPI and WMI

Some examples of retrieving data from WMI through TWAPI COM support.

Note that these examples are for illustrative purposes. Where possible, it is much more efficient to use TWAPI's commands that directly layer on top of the Win32 API instead of going through the COM/WMI layers.

All examples assume you have initialized with

  package require twapi
  set wmi [twapi::_wmi] # or set wmi [twapi::wmi_root] with 4.0 or later

and remember to do a

  $wmi -destroy

at the end


Example Scripts

Installed Applications

Show applications that are installed on the system (warning: may take a while to run)

  $wmi -with {
    {ExecQuery "select * from Win32_Product"}
  } -iterate app {
    puts "[$app Name] [$app Version]"
  }

Show installed Microsoft applications (warning: may take a while to run)

  $wmi -with {
    {ExecQuery "select * from Win32_Product where Vendor='Microsoft Corporation'"}
  } -iterate app {
    puts "[$app Name] [$app Version]"
  }

Show installed OS hotfixes

  $wmi -with {
    {ExecQuery "select * from Win32_QuickFixEngineering"}
  } -iterate app {
    puts "[$app HotFixID] [$app Description] installed by [$app InstalledBy]"
  }

BIOS Information

Print BIOS information

  $wmi -with {
    {ExecQuery "select * from Win32_BIOS"}
  } -iterate bios { 
    puts [$bios GetObjectText_]
  }

Print a specific BIOS field

  $wmi -with {
    {ExecQuery "select * from Win32_BIOS"}
  } -iterate bios {
    puts [$bios BiosVersion]
  }

Windows services

Print list of Windows services that are set to autostart.

  $wmi -with {
    {ExecQuery "select * from Win32_Service where StartMode='Auto'"}
  } -iterate svc {
    puts [$svc DisplayName]
  }

Network adapters

Print list of network adapters in the system.

  $wmi -with {
    {ExecQuery "select * from Win32_NetworkAdapter"}
  } -iterate net {
    puts "[$net DeviceID]:[$net Description]:[$net NetConnectionStatus]"
  }

Motherboard

Print motherboard manufacturer

  $wmi -with {
    {ExecQuery "select * from Win32_BaseBoard"}
  } -iterate mb {
    puts "[$mb Manufacturer] [$mb Model] [$mb Name] SN# [$mb SerialNumber]"
  }

WMI event handling

See Handling WMI events using TWAPI

neb Also, WMI has a nagging habit of hanging on random queries sometimes. There is no built-in way to cancel or add a timeout, unless you use an asynchronous query. Since that is essentially an event query, I have posted an example of that with the event examples.

USB

See TWAPI and USB for examples.

Discussion

veda: how do you connect to WMI on a remote server? APN Below is an example but Google for full WMI connection syntax.

  set wmi [twapi::comobj_object "winmgmts:{impersonationLevel=impersonate}!//COMPUTERNAME/root/cimv2"]

MHo: Here is something for which I don't have an explanation yet. The same thing happens using tcom. Using w2k.:

First, loading a tclsh (8.4.14):

 % expr 1.5*3.9
 5.85
 % package require twapi
 1.0
 % expr 1.5*3.9
 5.85
 % set wmi [twapi::_wmi]
 ::twapi::com_1
 % expr 1.5*3.9
 syntax error in expression "1.5*3.9": extra tokens at end of expression
 %

male - 2007-01-22:

First, some COM objects are specialized on the language the OS is working with. Second, some COM objects sets, without need, the locale of the application they are working in. Third, try after loading the WMI:

 % expr 1,5*3,9

I work, even being Germany, with an English OS, so I can't prove my thoughts!

But my experiences with the "Microsoft Services for UNIX" (NFS for Windows) showed me, that some Microsoft products are not developed with the right amount of sensitivity!

In our case the problem occurred, because NFS for Windows changed the locale of the application the DLLs are loaded in (e.g. because a file selection dialog needed the NFS environment) to a German one.

After a change of the locale, the numeric format might not use the period as floating point divider, but e.g. a comma! So the expression parser won't except the period anymore, but the comma in double values.

The tcl version 8.5 will eliminate that problem, because it won't use the system versions of strtoi, strtol, strtod, etc., which are locale dependent.

MHo: at this moment, I can't do further tests with w2k, because I'm sitting on my XP at home, where the problem does not exist (which indicates that you are right). Oh Microsoft...?

 > tclsh
 % expr 1.5*3.9
 5.85
 % package require twapi
 1.0
 % expr 1.5*3.9
 5.85
 % set wmi [twapi::_wmi]
 ::twapi::com_1
 % expr 1.5*3.9
 syntax error in expression "1.5*3.9": extra tokens at end of expression
 % expr 1,5*3,9
 syntax error in expression "1,5*3,9": extra tokens at end of expression
 % expr 1*3
 3

Using the comma as a separator doesn't help...So, after using TCOM or TWAPI to access WMI, usage of floating point numbers isn't possible anymore... do I really have to wait for Tcl 8.5 to solve this b i g problem???

male - 2007-01-23 (1):

What will happen if you "create" a double?

 % expr {double(1) / 3}

What string representation it will have?

APN Using , as a separator won't help because expr still parses the whole expression using "." as a separator and then passes individual numbers to str* and friends. Unfortunately, there is a mismatch between the expr parser and str* locale-based functions that I can't see how to solve (other than the Tcl 8.5 way). I ran into this with pdh.dll as well (performance counter) and the only way to fix it was to call setlocale(LC_ALL, "C") after every PDH call! I just find it incredible that a DLL would go about changing locales when it should really be using what the application sets.

male - 2007-01-23 (2):

Hhm - in our case (the NFS for Windows problem), the expr parser suddenly excepted doubles with "," as separator!

And we did the same like you APN - after each file selection the locale was changed back to "C" and everything worked.

I created a little locale tcl API, so that we were able to do this from tcl.

But ... I don't know, how a change back to the "normal" locale would influence the WMI?

MHo: I could test what happen with WMI after switching back if I would have this little tcl API you mentioned...

male - 2007-01-23 (2):

So MHo - I'll create a new wiki page setlocale API and will publish there the code, ok!

MHo: So, time for a coming-out: I have to install a C-compiler... something I avoided over the last 24 years ... lough lough. Ok, I'll see.

male - 2007-01-23 (3):

What's about mailing me MHo, so that I can answer back with an tcl 8.4 stubs enabled setlocale DLL?

male - 2007-01-29:

Sorry Matthias MHo, your eMail got stuck and deleted inside my Spam-Wall. Could you please resend it? Thanks!! MHo Just remailed (2007/02/19), Thx.

gh 2007-02-18 This problem occurs in PrintDouble (generic/tclUtil.c) using the sprintf function. This function sometimes respects locale and sometimes not. You can workaround this if you adjust locale settings in the Windows Control Panel, especially the decimal separator should be changed to "."