Определение идентификатора пакета и контекста среды выполнения

Возможно, у вас есть некоторые версии приложения, которые не были распространены в MSIX-пакете. Во время выполнения приложение можно определить, было ли оно развернуто как пакет MSIX с помощью API диспетчера пакетов Windows или собственного пользовательского установщика. Вам может потребоваться изменить поведение приложения, например параметры обновления, или воспользоваться преимуществами функций, доступных только для пакетов MSIX.

Чтобы определить, запущено ли ваше приложение в виде MSIX-пакета на версии Windows, поддерживающей полный набор возможностей MSIX, можно использовать собственную функцию GetCurrentPackageFullName в kernel32.dll. Если классическое приложение выполняется как неупакованное приложение без удостоверения пакета, эта функция возвращает ошибку, которая может помочь определить контекст, в котором выполняется приложение.

Если функция выполнена, это означает:

  • Приложение упаковывается в пакет MSIX.
  • Ваше приложение работает в Windows 10, версии 1709 (сборка 16299) или более поздней версии с полной поддержкой MSIX.

Использование GetCurrentPackageFullName в машинном коде

В следующем примере кода показано, как использовать GetCurrentPackageFullName для определения контекста приложения.

#define _UNICODE 1
#define UNICODE 1

#include <Windows.h>
#include <appmodel.h>
#include <malloc.h>
#include <stdio.h>

int __cdecl wmain()
{
    UINT32 length = 0;
    LONG rc = GetCurrentPackageFullName(&length, NULL);
    if (rc != ERROR_INSUFFICIENT_BUFFER)
    {
        if (rc == APPMODEL_ERROR_NO_PACKAGE)
            wprintf(L"Process has no package identity\n");
        else
            wprintf(L"Error %d in GetCurrentPackageFullName\n", rc);
        return 1;
    }

    PWSTR fullName = (PWSTR) malloc(length * sizeof(*fullName));
    if (fullName == NULL)
    {
        wprintf(L"Error allocating memory\n");
        return 2;
    }

    rc = GetCurrentPackageFullName(&length, fullName);
    if (rc != ERROR_SUCCESS)
    {
        wprintf(L"Error %d retrieving PackageFullName\n", rc);
        return 3;
    }
    wprintf(L"%s\n", fullName);

    free(fullName);

    return 0;
}

Использование функции GetCurrentPackageFullName в управляемом коде

Чтобы вызвать GetCurrentPackageFullName в управляемом приложении .NET Framework, необходимо использовать Вызов неуправляемого кода (P/Invoke) или другую форму взаимодействия.

Чтобы упростить этот процесс, можно использовать библиотеку DesktopBridgeHelpers. Эта библиотека поддерживает .NET Framework 4 и более поздних версий и использует P/Invoke внутри для предоставления вспомогательного класса, который определяет, выполняется ли приложение в версии Windows, поддерживающей полный набор функций MSIX. Эта библиотека также доступна в качестве пакета NuGet.

После установки пакета в проекте можно создать новый экземпляр класса DesktopBridge.Helpers и вызвать метод IsRunningAsUwp. Этот метод возвращает значение true, если приложение выполняется как пакет MSIX в Windows 10, версии 1709 (сборка 16299) или более поздней, и false, если это не так. В следующем примере показан вызов этого метода.

private bool IsRunningAsUwp()
{
   UwpHelpers helpers = new UwpHelpers();
   return helpers.IsRunningAsUwp();
}

private void Form1_Load(object sender, EventArgs e)
{
   if (IsRunningAsUwp())
   {
       txtUwp.Text = "I'm running as MSIX";
   }
   else
   {
       txtUwp.Text = "I'm running as a native desktop app";
   }
}