实现应用的试用版Implement a trial version of your app

如果你在 Windows 开发人员中心仪表板中将应用配置为免费试用,以便客户可以在试用期内免费使用你的应用,可通过在试用期内排除或限制某些功能吸引客户升级到应用的完整版。If you configure your app as a free trial in the Windows Dev Center dashboard so that customers can use your app for free during a trial period, you can entice your customers to upgrade to the full version of your app by excluding or limiting some features during the trial period. 请在开始编码之前确定哪些功能应受到限制,然后确保你的应用只在已购买完整版许可之后才允许这些功能运作。Determine which features should be limited before you begin coding, then make sure that your app only allows them to work when a full license has been purchased. 也可以在客户购买你的应用之前,启用仅在试用期才会出现的某些功能,如横幅或水印。You can also enable features, such as banners or watermarks, that are shown only during the trial, before a customer buys your app.

本文介绍如何使用 Windows.Services.Store 命名空间中 StoreContext 类的成员来确定用户是否有应用的试用许可证,以及在应用运行时许可证的状态发生更改的情况下是否获得通知。This article shows how to use members of the StoreContext class in the Windows.Services.Store namespace to determine if the user has a trial license for your app and be notified if the state of the license changes while your app is running.

备注

Windows.Services.Store 命名空间在 Windows 10 版本 1607 中引入,它仅可用于面向 Windows 10 周年纪念版(10.0;版本 14393)或 Visual Studio 更高版本的项目中。The Windows.Services.Store namespace was introduced in Windows 10, version 1607, and it can only be used in projects that target Windows 10 Anniversary Edition (10.0; Build 14393) or a later release in Visual Studio. 如果你的应用面向 Windows 10 的较早版本,则必须使用 Windows.ApplicationModel.Store 命名空间,而不是 Windows.Services.Store 命名空间。If your app targets an earlier version of Windows 10, you must use the Windows.ApplicationModel.Store namespace instead of the Windows.Services.Store namespace. 有关详细信息,请参阅此文章For more information, see this article.

实现试用版的指南Guidelines for implementing a trial version

应用的当前许可证状态存储为 StoreAppLicense 类的属性。The current license state of your app is stored as properties of the StoreAppLicense class. 通常,将取决于许可证状态的功能放在我们在下一步介绍的条件块中。Typically, you put the functions that depend on the license state in a conditional block, as we describe in the next step. 在考虑这些功能时,确保实现该功能的方式允许这些功能在所有许可证状态下均能正常工作。When considering these features, make sure you can implement them in a way that will work in all license states.

另外,决定你希望在应用运行时如何处理对应用许可证的更改。Also, decide how you want to handle changes to the app's license while the app is running. 你的试用版可以是全功能的,但具有付费版所没有的应用内广告横幅。Your trial app can be full-featured, but have in-app ad banners where the paid-for version doesn't. 或者,你的试用应用可以禁用某些功能,或定期显示消息要求用户购买应用。Or, your trial app can disable certain features, or display regular messages asking the user to buy it.

考虑你正设计的应用类型,什么是适合它的试用或到期策略。Think about the type of app you're making and what a good trial or expiration strategy is for it. 对于试用版的游戏,一个好的策略是限制用户可以玩的游戏内容量。For a trial version of a game, a good strategy is to limit the amount of game content that a user can play. 对于试用版的实用工具,可能需要考虑设置一个到期日期,或限制潜在购买者可以使用的功能。For a trial version of a utility, you might consider setting an expiration date, or limiting the features that a potential buyer can use.

对于大部分非游戏应用,设置一个过期日期很有用,因为用户可很好地理解整个应用。For most non-gaming apps, setting an expiration date works well, because users can develop a good understanding of the complete app. 以下是一些常见的过期场景和处理它们的选项。Here are a few common expiration scenarios and your options for handling them.

  • 试用许可证在应用正在运行时过期。Trial license expires while the app is running

    如果应用正在运行时试用许可证过期,应用可以:If the trial expires while your app is running, your app can:

    • 不执行任何操作。Do nothing.
    • 向客户显示一条消息。Display a message to your customer.
    • 关闭。Close.
    • 提示客户购买应用。Prompt your customer to buy the app.

    最佳做法是显示一条消息,提示客户购买应用,如果客户购买它,则继续启用所有功能。The best practice is to display a message with a prompt for buying the app, and if the customer buys it, continue with all features enabled. 如果用户决定不购买应用,则关闭它或定期提醒他们购买应用。If the user decides not to buy the app, close it or remind them to buy the app at regular intervals.

  • 在应用启动前试用许可证过期。Trial license expires before the app is launched

    如果在应用启动前试用许可证过期,应用将不会启动。If the trial expires before the user launches the app, your app won't launch. 相反,用户将看到一个对话框,该对话框为用户提供从应用商店购买你的应用的选项。Instead, users see a dialog box that gives them the option to purchase your app from the Store.

  • 客户在应用运行时购买它Customer buys the app while it is running

    如果客户在应用运行时购买它,以下是应用可执行的一些操作。If the customer buys your app while it is running, here are some actions your app can take.

    • 不执行任何操作,让他们继续在试用模式下操作,直到重新启动应用。Do nothing and let them continue in trial mode until they restart the app.
    • 感谢他们购买,或者显示一条消息。Thank them for buying or display a message.
    • 静默启用在完整许可证下可用的功能(或禁用仅限试用的通知)。Silently enable the features that are available with a full-license (or disable the trial-only notices).

请务必阐述你的应用在免费试用期间及之后的行为,以便客户不会对应用行为感到惊讶。Be sure to explain how your app will behave during and after the free trial period so your customers won't be surprised by your app's behavior. 有关描述应用的详细信息,请参阅创建应用提要For more info about describing your app, see Create app descriptions.

先决条件Prerequisites

本示例有以下先决条件:This example has the following prerequisites:

  • 适用于面向 Windows 10 周年纪念版(10.0;版本 14393)或更高版本的通用 Windows 平台 (UWP) 应用的 Visual Studio 项目。A Visual Studio project for a Universal Windows Platform (UWP) app that targets Windows 10 Anniversary Edition (10.0; Build 14393) or a later release.
  • 你已在 Windows 开发人员中心仪表板中创建了一个应用(已配置为免费试用,没有时间限制),并且该应用已在应用商店中发布。You have created an app in the Windows Dev Center dashboard that is configured as a free trial with no time limit and this app is published in the Store. 在测试应用期间,你可以选择将应用配置为在 Microsoft Store 中隐藏。You can optionally configure the app so it is not discoverable in the Store while you test it. 有关详细信息,请参阅我们的测试指南For more information, see our testing guidance.

此示例中的代码假设:The code in this example assumes:

  • 代码在含有 ProgressRing(名为 workingProgressRing)和 TextBlock(名为 textBlock)的 Page 上下文中运行。The code runs in the context of a Page that contains a ProgressRing named workingProgressRing and a TextBlock named textBlock. 这些对象分别用于指示是否正在进行异步操作和显示输出消息。These objects are used to indicate that an asynchronous operation is occurring and to display output messages, respectively.
  • 代码文件有一个适用于 Windows.Services.Store 命名空间的 using 语句。The code file has a using statement for the Windows.Services.Store namespace.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 有关详细信息,请参阅应用内购买和试用For more information, see In-app purchases and trials.

备注

如果你有使用桌面桥的桌面应用程序,可能需要添加不在此示例中显示的额外代码来配置 StoreContext 对象。If you have a desktop application that uses the Desktop Bridge, you may need to add additional code not shown in this example to configure the StoreContext object. 有关详细信息,请参阅在使用桌面桥的桌面应用程序中使用 StoreContext 类For more information, see Using the StoreContext class in a desktop application that uses the Desktop Bridge.

代码示例Code example

初始化你的应用时,为你的应用获取 StoreAppLicense 对象并处理 OfflineLicensesChanged 事件,以在应用运行时许可证发生更改的情况下收到通知。When your app is initializing, get the StoreAppLicense object for your app and handle the OfflineLicensesChanged event to receive notifications when the license changes while the app is running. 例如,如果试用期到期或客户通过应用商店购买应用,应用的许可证将发生更改。For example, the app's license could change if the trial period expires or the customer buys the app through a Store. 当许可证发生更改时,获取新的许可证并相应地启用或禁用应用的功能。When the license changes, get the new license and enable or disable a feature of your app accordingly.

此时,如果用户购买了应用,则向用户提供许可状态已发生更改的反馈是一个好做法。At this point, if a user bought the app, it is a good practice to provide feedback to the user that the licensing status has changed. 你可能需要请求用户重新启动应用(如果你已经这样编码)。You might need to ask the user to restart the app if that's how you've coded it. 但是一定要让这一过渡尽可能无缝和轻松地进行。But make this transition as seamless and painless as possible.

private StoreContext context = null;
private StoreAppLicense appLicense = null;

// Call this while your app is initializing.
private async void InitializeLicense()
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
        // If your app is a desktop app that uses the Desktop Bridge, you
        // may need additional code to configure the StoreContext object.
        // For more info, see https://aka.ms/storecontext-for-desktop.
    }

    workingProgressRing.IsActive = true;
    appLicense = await context.GetAppLicenseAsync();
    workingProgressRing.IsActive = false;

    // Register for the licenced changed event.
    context.OfflineLicensesChanged += context_OfflineLicensesChanged;
}

private async void context_OfflineLicensesChanged(StoreContext sender, object args)
{
    // Reload the license.
    workingProgressRing.IsActive = true;
    appLicense = await context.GetAppLicenseAsync();
    workingProgressRing.IsActive = false;

    if (appLicense.IsActive)
    {
        if (appLicense.IsTrial)
        {
            textBlock.Text = $"This is the trial version. Expiration date: {appLicense.ExpirationDate}";

            // Show the features that are available during trial only.
        }
        else
        {
            // Show the features that are available only with a full license.
        }
    }
}

有关完整的应用程序示例,请参阅 Microsoft Store 示例For a complete sample application, see the Store sample.