How to get win32 COM objects e.g., to find hardware details

I'd like to find out some hardware details on Windows. This is straightforward in Python:

import win32com.client
obj = win32com.client.GetObject('winmgmts:Win32_Processor')
# ... get the details ...

But searching for getobject in the winapi crate doesn't produce any results, so I don't know if it is supported.
There's also a com_rs crate, but it hasn't been updated in more than a year and doesn't have any examples.

Does anyone have some example code that would get me started?

2 Likes

In Rust working with COM is pretty similar to working with COM in C++. First you'd need to have the COM interface definitions. If winapi doesn't have the COM interfaces you'll be using then you'll have to bind to the interface yourself using the RIDL! macro from winapi. Then you have to figure out what function to call to instantiate an instance of that interface. Typically you'd use CoCreateInstance to instantiate a COM object, but some APIs like DirectX have a special function to instantiate a factory object used to instantiate further objects.

Once you have your object you'd probably want to use some sort of ComPtr smart pointer to automatically handle AddRef/Release stuff. wio provides this for example: https://github.com/retep998/wio-rs/blob/master/src/com.rs

You probably are interested in the WMI COM api, so you can find more documentation on it at COM API for WMI - Win32 apps | Microsoft Docs

As it turns out there is already a PR for winapi that adds bindings to the WMI stuff so it won't be too long before it'll be merged and you can work off a fork for now if you want. https://github.com/retep998/winapi-rs/pull/603

4 Likes

Thanks for that. I'll wait for the wmi bindings to arrive in winapi.

Just wondered if WMI is yet supported in Rust? At the moment I'm having to bundle a tiny Go program with my Rust application since Go has this library Go wmi. This lets me use the WMI query language, e.g., select ProcessorID from Win32_Processor etc.

WMI support has been merged into winapi. I haven't yet published it to crates.io but you can already start using it by depending on winapi via a git dependency.

1 Like

Thanks for doing that! Now all I have to do is figure out how to use it... Does anyone have any examples of using Rust with WMI queries?

There aren't any Rust examples that I know of. However there are plenty of C++ examples which is pretty similar to what you'd do in Rust.

Thanks for that. Looks like I've been spoiled by the high level wrappers available for Python and Go since I've never had to do anything as complicated as those examples. Anyway, I'll give it a try.

I am trying unsuccessfully to port a C++ WMI example to Rust. The example is provided by Microsoft:
WMI C++ eg.

It requires a macro called FAILED which for now I'm faking by writing if hres != winerror::S_OK { return None } or similar.

But it also requires a type called IWbemLocator and that doesn't seem to be in the Rust win32 API.

So I'm stuck.

(Rather hoping that some Windows-savvy Rustaceans have already implemented WMI query (WQL) support; but haven't found it on crates.io.)

IWbemLocator does exist in the git version of winapi, it's just not published to crates.io yet. I've also recently added the FAILED function so you can correctly test if an HRESULT indicates failure.

2 Likes