Search code examples
c++uwpc++-winrt

C++/WinRT UWP - HRESULT 0x80073D54 : The process has no package identity


I'm working with C++/WinRT for UWP. I am trying to create a file, but an exception is thrown at line 11 :

#include "pch.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;

IAsyncAction createFile()
{
    try
    {
        StorageFolder local{ ApplicationData::Current().LocalFolder() }; // line 11
        StorageFolder folder = co_await local.CreateFolderAsync(L"myapp", CreationCollisionOption::OpenIfExists);
        StorageFile file = co_await folder.CreateFileAsync(L"file", CreationCollisionOption::ReplaceExisting);

        co_await FileIO::WriteTextAsync(file, L"wide chars here.");
    }
    catch (const winrt::hresult_error& ex)
    {

    }
}

int main()
{
    init_apartment();
    createFile();
}

The debugger doesn't shows me the error, because it crashes. The output says

onecoreuap\base\appmodel\statemanager\winrt\lib\windows.storage.applicationdatafactory.server.cpp(126)\Windows.Storage.ApplicationData.dll!00007FFE8A7A1202: (caller: 00007FFE8A799081) ReturnHr(1) tid(3ad8) 80073D54 The process has no package identity.
onecoreuap\base\appmodel\statemanager\winrt\lib\windows.storage.applicationdatafactory.server.cpp(74)\Windows.Storage.ApplicationData.dll!00007FFE8A7990A9: (caller: 00007FF733954323) ReturnHr(2) tid(3ad8) 80073D54 The process has no package identity.
Debug Error!

Program: D:\Developpement\CPP\test\x64\Debug\Tests.exe

abort() has been called

I found nothing about it on google, so what could this error mean, and how can I solve it ? Thanks


Solution

  • The issue here is with ApplicationData::Current(). https://learn.microsoft.com/en-us/uwp/api/windows.storage.applicationdata.current?view=winrt-18362

    The API to get current application information is based on the identity of the application. Any Windows App can have identity (it doesn't have to be a UWP), but it must be installed using the packaged installer to get it (a.k.a. MSIX installer). You can learn more about packaged "full trust" applications here: https://learn.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-prepare

    You can use the desktop app packaging project here to make it a bit easier to wrap your app up: https://learn.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-packaging-dot-net

    All that said, if you just want to open a file in app local data, without getting into the issue of packaging, you can create folders based on the location of %appdata%. Without a packaged installer, it's your responsibility to handle cleanup.

    So it's more work in the short term to set up your application as a packaged app, but if this is something that you want to distribute, taking care of this up front will likely save you a lot of work in the long run.

    If you want to manually set up an app folder, you can do something along these lines to get started:

    int main()
    {
        init_apartment();
    
        wstring appfolderstring;
        appfolderstring.resize(ExpandEnvironmentStrings(L"%AppData%", nullptr, 0));
        ExpandEnvironmentStringsW(L"%AppData%", &appfolderstring.front(), appfolderstring.size());
        wprintf(L"path: %ls!\n", appfolderstring.c_str());
    
        // Note: off-by-one issue... ExpandEnvironmentStringsW wants to write the final null character.
        // Leave buffer space to write it above, then trim it off here.
        appfolderstring.resize(appfolderstring.size()-1);
    
        StorageFolder folder{ StorageFolder::GetFolderFromPathAsync(appfolderstring).get() };
        printf("folder: %ls!\n", folder.DisplayName().c_str());
    }