Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inconvenient c++/winrt language projection? Constructor of MdmSessionManger will always be deleted after regeneration. Why has it been done this way?

I am writing some UEM (= Unified Endpoint Management) tools and need to sync my client
with the UEM Server. To do this i use C++ and winrt (= Windows runtime)

I extracted a part of the code to show you my problem. The code works after you change one line in a generated header file. The program does what is is supposed to do and
does it fast. To run the code, you need an MDM enrolled Windows Client. To recreate the problem, you only need your compiler.

#include "pch.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Management;

#include <iostream>
#include <chrono>
#include <thread>
using namespace std;

int main()
{
    winrt::init_apartment(); //initialise winrt

    //create a session
    auto session = winrt::Windows::Management::MdmSessionManager().TryCreateSession();

    //start the sync
    session.StartAsync();

    //show some output
    cout << "Start async command launched.\n";

    while (session.State() != MdmSessionState::Completed)
    {
        switch (session.State())
        {
        case MdmSessionState::NotStarted:
            cout << "Not started\n";
            break;
        case MdmSessionState::Starting:
            cout << "Starting\n";
            break;
        case MdmSessionState::Connecting:
            cout << "Connecting\n";
            break;
        case MdmSessionState::Communicating:
            cout << "Communicating\n";
            break;
        case MdmSessionState::AlertStatusAvailable:
            cout << "Alert occured\n";
            break;
        case MdmSessionState::Retrying:
            cout << "Retrying\n";
            break;
        case MdmSessionState::Completed:
            cout << "Completed\n";
            break;
        default:
            cout << "Unknown Status";
            break;
        }
        std::this_thread::sleep_for(chrono::milliseconds(10)); //make it slower
    }

    cout << "Finished.\n";
}

The output looks like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Start async command launched.
Not started
Not started
Not started
Not started
Not started
Connecting
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Communicating
Finished.

On the server side I can verify that the client has synced, so far so good.

Every time I clean and completely recompile my project, I get the following error:

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler MSB6006 "CL.exe" wurde mit dem Code 2 beendet. WinRTtest C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets 702

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2280 "winrt::Windows::Management::MdmSessionManager::MdmSessionManager(void)" : Es wurde versucht, auf eine gelöschte Funktion zu verweisen WinRTtest C:\Dataport\transfer\WinRTtest\WinRTtest\main.cpp 17

The problem is easy to find. My compiler recreates "Windows.Mangement.2.h" and generated the following code:

// WARNING: Please don't edit this file. It was generated by C++/WinRT v2.0.220531.1

#pragma once
#ifndef WINRT_Windows_Management_2_H
#define WINRT_Windows_Management_2_H
#include "winrt/impl/Windows.Management.1.h"
WINRT_EXPORT namespace winrt::Windows::Management
{
    struct __declspec(empty_bases) MdmAlert : winrt::Windows::Management::IMdmAlert
    {
        MdmAlert(std::nullptr_t) noexcept {}
        MdmAlert(void* ptr, take_ownership_from_abi_t) noexcept : winrt::Windows::Management::IMdmAlert(ptr, take_ownership_from_abi) {}
        MdmAlert();
    };
    struct __declspec(empty_bases) MdmSession : winrt::Windows::Management::IMdmSession
    {
        MdmSession(std::nullptr_t) noexcept {}
        MdmSession(void* ptr, take_ownership_from_abi_t) noexcept : winrt::Windows::Management::IMdmSession(ptr, take_ownership_from_abi) {}
    };
    struct MdmSessionManager
    {
        MdmSessionManager() = delete;
        [[nodiscard]] static auto SessionIds();
        static auto TryCreateSession();
        static auto DeleteSessionById(param::hstring const& sessionId);
        static auto GetSessionById(param::hstring const& sessionId);
    };
}
#endif

The headache comes from the following line of code:

"MdmSessionManager() = delete;"

To make the program compile, I commented this line out. Yes, I know and I read the warning: "// WARNING: Please don’t edit this file. It was generated by C++/WinRT v2.0.220531.1"

The question is: "Why does winrt generates the MdmSessionManager and deletes its constructor? If I just change it and compile the project, it works. (until I do a full recompile) This is very inconvenient.
Might this be a bug in the c++ winrt language projection? Am I doing something wrong?

I would expect the language projection to make it possible to construct a "MdmSessionManager" so it can be used in code. It does not feel right to delete it’s constructor. Perhaps this is done for a certain reason. It would be nice if somebody can explain the reason behind it.

>Solution :

MdmSessionManager contains static class members exclusively. As such it is not intended to be instantiated, hence its default constructor is delete-d.

To access its class members you’ll need to use the qualified name, e.g.

auto session = winrt::Windows::Management::MdmSessionManager::TryCreateSession();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading