CreatePushNotificationChannelForApplicationAsync i

2019-07-17 03:26发布

问题:

I'm trying to use windows push notifications in native C++ code. But I struggle with implementation. I'm calling CreatePushNotificationChannelForApplicationAsync but it returns HRESULT_FROM_WIN32(ERROR_NOT_FOUND) : Element not found.

My OS is Win10 and I use Visual Studio 2015.

Here is my code:

#include <wrl.h>
#include <windows.networking.pushnotifications.h>
#include <ppltasks.h>

#pragma comment(lib, "runtimeobject.lib")

using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Networking::PushNotifications;
using namespace concurrency;

int main(char* argv[], int argc)
{
    RoInitializeWrapper init(RO_INIT_MULTITHREADED);
    if ( FAILED(init) )
        return 0;

    ComPtr<IPushNotificationChannelManagerStatics> channelManager;
    HRESULT hr = GetActivationFactory(HStringReference(L"Windows.Networking.PushNotifications.PushNotificationChannelManager").Get(), &channelManager);

    if ( FAILED(hr) )
        return 0;

    IAsyncOperation<PushNotificationChannel*>* asyncOp;
    hr = channelManager->CreatePushNotificationChannelForApplicationAsync(&asyncOp); // return HRESULT_FROM_WIN32(ERROR_NOT_FOUND)

    if ( FAILED(hr) )
        return 0;

    // create task to obtain uri from asyncOp

    return 0;
}

On the other hand it is pretty straightforward in WinRT.

namespace WnsPushAPI
{
    public ref class WnsWrapper sealed
    {
    public:

        void ObtainUri()
        {
            IAsyncOperation<PushNotificationChannel^>^ channelOperation = PushNotificationChannelManager::CreatePushNotificationChannelForApplicationAsync();
            auto channelTask = create_task(channelOperation);
            channelTask.then([this](PushNotificationChannel^ channel) {
                // ... Save URI for latter use. channel->Uri->Data()
                channel->PushNotificationReceived += ref new TypedEventHandler<PushNotificationChannel^, PushNotificationReceivedEventArgs^>(this, &WnsWrapper::OnNotify);
            }, task_continuation_context::use_current());
        }

        void OnNotify(PushNotificationChannel^ sender, PushNotificationReceivedEventArgs^ e)
        {
            // do something
        };
    };
}

I also checked generated code with /d1ZWtokens compiler switch but I didn't find anything useful. Documentation for push notification for native C++ is really poorly written and I couldn't find and example in native C++.

回答1:

Your code is okay. The problem lies in the fact that you can only register for push notifications from Windows Store applications. You cannot do that from desktop applications. The error comes from the fact that the system cannot find your AppX package identity.



回答2:

@elanius Have you solved the issue?

ComPtr<IPushNotificationChannelManagerStatics> channelManager = NULL;
        HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Networking_PushNotifications_PushNotificationChannelManager).Get(), &channelManager);

IAsyncOperation<PushNotificationChannel*>* asyncOp; 
hr = channelManager->CreatePushNotificationChannelForApplicationAsync(&asyncOp);

channelManager: Got "No symbols loaded for wpnapps.dll". and asyncOp is NULL.



回答3:

I also faced same HRESULT_FROM_WIN32(ERROR_NOT_FOUND) error while trying to use WNS from my desktop app. Just in case anyone also faces this issue I'd like to mention CreatePushNotificationChannelForApplicationAsync works fine from Desktop Bridge. Here is the code that I used. Note it is winrt based, and I think WRL based code also would work without any problem, just need to wrap desktop app with Desktop Bridge.

winrt::init_apartment();
PushNotificationChannelManagerForUser manager = PushNotificationChannelManager::GetDefault();
IAsyncOperation<PushNotificationChannel> async = manager.CreatePushNotificationChannelForApplicationAsync();

async.Completed([](auto && result, auto && status) {
    auto channel = result.GetResults();
});