How do I get the computer’s serial number? Consuming Windows Runtime classes in desktop apps, part 3: C++/WinRT


Continuing our series on getting the computer's serial number in desktop apps in various languages, next up is C++/WinRT.

From Visual Studio, create a new C++ Console Application that goes like this:

#include <windows.h>
#include <stdio.h> // Horrors! Mixing C and C++!

#include "winrt/Windows.System.Profile.SystemManufacturers.h"

int __cdecl wmain(int, char**)
{
  winrt::init_apartment();
  {
    auto serialNumber = winrt::Windows::System::Profile::
         SystemManufacturers::SmbiosInformation::SerialNumber();
    wprintf(L"Serial number = %ls\n", serialNumber.c_str());
  }

  // The last thread cleans up before uninitializing for good.
  winrt::clear_factory_cache();
  winrt::uninit_apartment();

  return 0;
}

Before building, prepare the project as follows:

  • Right-click the Project in Visual Studio and select Manage NuGet packages. Click the Browse tab and search for "cppwinrt", then click Install.
  • Right-click the Project in Visual Studio and select Properties. Configure the project as follows:
    • Configuration Properties, C/C++ Language C++ Language Standard: Set to ISO C++17 Standard (/std:c++17).
    • Configuration Properties, Linker, Inputs, Additional Dependencies: add windowsapp.lib.

Okay, now you can build and run the program.

C++/WinRT lets you consume Windows Runtime objects without requiring any nonstandard language extensions. It's all standard C++17.

So that's native code. Next up is C#.

Bonus chatter:

Comments (15)

  1. camhusmj38 says:

    C++/winrt is included in the latest preview Windows SDK. So you for the preview SDK and for RS4 SDKs you can skip the NuGet step.

  2. Marcos Kirchner says:

    I might have done something diferent, but the only way I could get it to work is changing the namespace to winrt::Windows::System::Profile::SystemManufacturers. I had to qualify it with “winrt” and there is a “Profile” part in the middle as well.

    1. Willem van Rumpt says:

      Same here. I’m also wondering why the two statements retrieving and printing were in a separate code block.

      1. Wayne says:

        The block is so that serialNumber will get cleaned up before the code to uninitialize the apartment.

        1. Willem van Rumpt says:

          Ah, okay :)
          But the destruction order for stack objects is well defined in C++, and “serialNumber” is guaranteed/should be/ ought to be destroyed before calling winrt::uninit_apartment(). Am I missing something?

          (Disclaimer: I have exactly zero experience with using C++ in a WinRT setting (or COM, for that matter)).

          1. Louis says:

            There’s no stack object corresponding to winrt::uninit_apartment(). That’s just a regular method call. Without the extra scope, serialNumber would be cleaned up after the return.

          2. camhusmj38 says:

            No, uninit_appartment is a function call. The braces are necessary because otherwise serialNumber would be destroyed when it goes out of scope at the end of main. If serialNumber was inlined into the print statement, it would go out of scope at the end of the line so no braces needed.

          3. Kenny Kerr says:

            It doesn’t actually matter. Since ‘serialNumber’ is an hstring (and not backed by a COM object), it can happily outlive the apartment.

          4. True, it doesn’t matter in this case, but in the more general case you may have references to runtime objects that need to be run down early.

          5. kantos says:

            The fact that there isn’t an RAII wrapper for the apartment has actually been a bit of a frustration for me using C++/WinRT. It’s not hard to write one, I basically re-purposed Raymond’s CCoinitialize, but it would be a nice thing to have.

          6. Willem van Rumpt says:

            *Sigh*, finally all your comments switched on the light. Somehow it didn’t register.
            Without the block, “serialNumber” outlives the call to winrt::uninit_apartment(), leaving “serialNumber” in a state where it has to destruct itself from an uninitialized apartment. I really ought to spend more time on C++ again.

  3. Joshua says:

    auto is a great language feature. That doesn’t mean it’s always good for learning. I’m pretty sure that’s a string but it could be something more exotic. I’m pretty sure you could smuggle a hat pointer in there.

  4. Peter Doubleday says:

    It’s an aside, I know, but isn’t it wonderful that we now have ASCIIZ strings, WCHAR strings, BSTRs, std::strings and now (if I read the comments above correctly) hstrings?

    What will the wonderful modern world of programming come up with next, I wonder?

    I’d also like to know why there are two statements inside that block, rather than a single statement that obviates the need to declare the auto … well, no, I wouldn’t actually. I think I can figure the answer out for myself.

    1. I broke it up into two lines just so you can see the two parts of the operation. (1) Getting the serial number. (2) Printing it. Because you are more likely to have some other step 2, like (2) save it somewhere.

  5. henke37 says:

    Automatic rt apartment manager utility class when?

Skip to main content