Search code examples
cwin-universal-appwindows-10-universal

How to get install location of UWP app in C?


In the past I wrote a game using the C programming language. Recently I was exploring the idea of porting it to the Universal Windows Platform, and potentially to the Windows Store.

After reading the docs, and spending some time on it, I managed to properly package it, and successfully install it locally as a UWP app.

I realized however, that up until now, the game was distributed as one folder, that when launched will look for the game's files locally. This means that if the game is run from a different folder (like when using a shortcut) it won't be able to find the local files to read. This is also a problem when it becomes a UWP app, since it is installed in the system, and can be launched from anywhere.

I've read in the docs this page: File access permissions, which describes how to get the install directory and read files from it. However the examples given are in C#.

How can I implement a similar functionality in C? The ideal solution would let me read files that are part of the package when it's installed.


Solution

  • As discussed in the comments, the UWP API is also available in C++ (either C++/CX or C++/WinRT). As far as I'm aware there is no pure C API available, but an option is to create a custom abstraction using an extern "C" header.

    An example of this could look something like this (untested, and heavily leaning on the file reading code found in the open-source project Kinc: https://github.com/Kode/Kinc/blob/master/Sources/kinc/io/filereader.winrt.cpp#L159)

    Header

    #ifdef _cplusplus
    extern "C"
    #endif
    const char* getAppLocation(void);
    

    Implementation (C++/CX)

    #include <Windows.h>
    
    extern "C" const char* getAppLocation(void) {
        static char filepath[1001];
        Platform::String ^ locationString = Windows::ApplicationModel::Package::Current->InstalledLocation->Path;
        WideCharToMultiByte(CP_UTF8, 0, locationString->Begin(), -1, filepath, 1000, nullptr, nullptr);
        return filepath;
    }