Попытка получить доступ к классу EmailWessage UWP из C ++ приводит к ошибке «REGDB_E_CLASSNOTREG Class not зарегистрирован» - PullRequest
0 голосов
/ 12 февраля 2020

Моя цель - использовать Класс EmailMessage , чтобы позволить пользователям моего настольного приложения взаимодействовать с Windows Почтовым приложением на Windows 10. В качестве теста я пытаюсь следующее из стандартного консольного приложения C ++ в Visual Studio 2017:

#include <Windows.h>
#include <roapi.h>
#pragma comment(lib, "runtimeobject.lib")
#include <Windows.Services.Store.h>
#include <wrl.h>

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Services::Store;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::System;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::ApplicationModel::Email;


HRESULT hr;
if(SUCCEEDED(hr = RoInitialize(RO_INIT_MULTITHREADED)))
{
    ComPtr<IEmailMessage> pEmlMsg;
    hr = RoGetActivationFactory(HStringReference(L"Windows.ApplicationModel.Email").Get(), __uuidof(pEmlMsg), &pEmlMsg);
    if (SUCCEEDED(hr) &&
        pEmlMsg)
    {
        //... keep going

    }
    else
        wprintf(L"ERROR: 0x%x RoGetActivationFactory\n", hr);

    RoUninitialize();
}

Но мой RoGetActivationFactory вызов выше всегда возвращает REGDB_E_CLASSNOTREG Class not registered.

Любая идея, что я там скучаю?

PS. Я проверяю это на Windows 10 v.1903 build 18362.239.

1 Ответ

2 голосов
/ 12 февраля 2020

вы получили REGDB_E_CLASSNOTREG Класс не зарегистрирован , поскольку "Windows .ApplicationModel.Email" действительно не зарегистрировано. ( посмотрите под ключом HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId - здесь нет Windows.ApplicationModel.Email подключа )

у вас 2 ошибки в коде, вместо собственной строки "Windows .ApplicationModel.Email" - вам нужно использовать RuntimeClass_* строк, определенных в некотором заголовочном файле winrt. вам нужно использовать

RuntimeClass_Windows_ApplicationModel_Email_EmailMessage

, который объявлен в Windows .ApplicationModel.email.h

, тогда RoGetActivationFactory не может вернуться IEmailMessage прямой. он может вернуть интерфейс IActivationFactory ( Вы можете получить указатель IActivationFactory, вызвав функцию RoGetActivationFactory. ), а затем вам нужно вызвать IActivationFactory::ActivateInstance для получения указателя на IInspectable и, наконец, QueryInterface для него для получения IEmailMessage

так что лучше (если вам нужен единственный экземпляр IEmailMessage) используйте RoActivateInstance здесь , код может быть следующим

#include <winstring.h>
#include <roapi.h>
#include <Windows.ApplicationModel.email.h>

void CALLBACK ep(void*)
{
    if (0 <= RoInitialize(RO_INIT_MULTITHREADED))
    {
        HSTRING_HEADER hsh;
        HSTRING activatableClassId;
        IInspectable* instance;
        ABI::Windows::ApplicationModel::Email::IEmailMessage* pEmlMsg;

        WindowsCreateStringReference(RuntimeClass_Windows_ApplicationModel_Email_EmailMessage, 
            _countof(RuntimeClass_Windows_ApplicationModel_Email_EmailMessage) - 1, 
            &hsh, &activatableClassId);

        if (0 <= RoActivateInstance(activatableClassId, &instance))
        {
            HRESULT hr = instance->QueryInterface(IID_PPV_ARGS(&pEmlMsg));

            instance->Release();

            if (0 <= hr)
            {
                //...
                // some demo usage
                static const WCHAR body[] = L"-- demo --";
                WindowsCreateStringReference(body, _countof(body) - 1, &hsh, 
                         &activatableClassId);

                if (0 <= pEmlMsg->put_Body(activatableClassId))
                {
                    if (0 <= pEmlMsg->get_Body(&activatableClassId))
                    {
                        DbgPrint("%S\n", 
                           WindowsGetStringRawBuffer(activatableClassId, 0));

                        WindowsDeleteString(activatableClassId);
                    }
                }

                pEmlMsg->Release();
            }
        }

        RoUninitialize();
    }
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...