检测包标识和运行时上下文Detect package identity and runtime context

你的应用程序可能有某些版本不是在 MSIX 包中分发的。You may have some versions of your app that were not distributed in an MSIX package. 在运行时,应用可以通过使用 Windows 包管理器 API 或你自己的自定义安装程序来检测自己是不是作为 MSIX 包部署。At runtime your app can detect whether it was deployed as an MSIX package by using the Windows Package Manager API, or your own custom installer. 可以更改更新设置等应用行为,也可以利用仅适用于 MSIX 包的功能。You may want to change the app behavior such as update settings or you may want to take advantage of functionality only available to MSIX packages.

若要确定应用程序是在支持完整 MSIX 功能集的 Windows 版本上作为 MSIX 包运行,可在 kernel32.dll 中使用 GetCurrentPackageFullName 本机函数。To determine whether your application is running as an MSIX package on a version of Windows that supports the full MSIX feature set, you can use the GetCurrentPackageFullName native function in kernel32.dll. 当桌面应用程序作为没有包标识的非包装应用程序运行时,此函数会返回一个错误,它能帮助你推断应用运行的上下文。When a desktop application is running as a non-packaged application without package identity, this function returns an error which can help you infer the context in which the app is running.

如果函数成功,这意味着:If the function succeeds, it means:

  • 你的应用包装在 MSIX 包中。Your app is packaged in an MSIX package.
  • 你的应用可以在 Windows 10 版本 1709(内部版本 16299)或更高版本的应用上运行,可获得完整的 MSIX 支持。Your app is running on Windows 10, version 1709 (build 16299) or later with full MSIX support.

在本机代码中使用 GetCurrentPackageFullNameUse GetCurrentPackageFullName in native code

以下代码示例演示了如何使用 GetCurrentPackageFullName 来确定应用的上下文。The following code example demonstrates how to use GetCurrentPackageFullName to determine the context of an app.

#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 函数Use GetCurrentPackageFullName function in managed code

若要在托管 .NET Framework 应用中调用 GetCurrentPackageFullName需要使用 Platform Invoke (P/Invoke) 或其他形式的互操作。To call GetCurrentPackageFullName in a managed .NET Framework app, you'll need to use Platform Invoke (P/Invoke) or some other form of interop.

若要简化此过程,可以使用 DesktopBridgeHelpers 库。To simplify this process, you can use the DesktopBridgeHelpers library. 此库支持 .NET Framework 4 及更高版本,并在内部使用 P/Invoke 来提供帮助器类,以确定应用是否在支持完整 MSIX 功能集的 Windows 版本上运行。This library supports .NET Framework 4 and later, and it uses P/Invoke internally to provide a helper class that determines whether the app is running on a version of Windows that supports the full MSIX feature set. 此库还可以 NuGet 包的形式提供。This library is also available as a NuGet Package.

在项目中安装包后,可以创建 DesktopBridge.Helpers 类的新实例,并调用 IsRunningAsUwp 方法。After you install the package in your project, you can create a new instance of the DesktopBridge.Helpers class and call the IsRunningAsUwp method. 如果你的应用作为 MSIX 包在 Windows 10 版本 1709(内部版本 16299)或更高版本上运行,则此方法返回 true;如果不满足以上任意条件,则返回 false。This method returns true if your app is running as an MSIX package on Windows 10, version 1709 (build 16299) or later and false if either of those are not true. 下面的示例演示如何调用此方法。The following sample demonstrates how to call this method.

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";
   }
}