使用 Windows.ApplicationModel.Store 命名空间的应用内购买和试用In-app purchases and trials using the Windows.ApplicationModel.Store namespace

可以使用 Windows.ApplicationModel.Store 命名空间中的成员,将应用内购买和试用功能添加到通用 Windows 平台 (UWP) 应用,以帮助通过应用盈利。You can use members in the Windows.ApplicationModel.Store namespace to add in-app purchases and trial functionality to your Universal Windows Platform (UWP) app to help monetize your app. 这些 API 还提供应用的许可证信息访问权限。These APIs also provide access to the license info for your app.

本部分中的文章提供有关针对多个常见方案使用 Windows.ApplicationModel.Store 命名空间中的成员的深入指南和代码示例。The articles in this section provide in-depth guidance and code examples for using the members in the Windows.ApplicationModel.Store namespace for several common scenarios. 有关与 UWP 中的应用内购买相关的基本概念概述,请参阅应用内购买和试用For an overview of basic concepts related to in-app purchases in UWP apps, see In-app purchases and trials. 有关演示如何使用 Windows.ApplicationModel.Store 命名空间实现试用和应用内购买的完整示例,请参阅应用商店示例For a complete sample that demonstrates how to implement trials and in-app purchases using the Windows.ApplicationModel.Store namespace, see the Store sample.

重要

Windows.ApplicationModel.Store 命名空间不再更新新功能。The Windows.ApplicationModel.Store namespace is no longer being updated with new features. 如果你的项目针对的是 Visual Studio 中的 Windows 10 周年纪念版(10.0;版本 14393) 或更高版本(即,针对 Windows 10 版本 1607 或更高版本),我们建议你使用 Windows.Services.Store 命名空间。If your project targets Windows 10 Anniversary Edition (10.0; Build 14393) or a later release in Visual Studio (that is, you are targeting Windows 10, version 1607, or later), we recommend that you use the Windows.Services.Store namespace instead. 有关详细信息,请参阅应用内购买和试用For more information, see In-app purchases and trials. 在使用桌面桥的 Windows 桌面应用程序或使用开发人员中心开发沙盒的应用或游戏中,Windows.ApplicationModel.Store命名空间不受支持(例如,与 Xbox Live 集成的任何游戏都是这种情况)。The Windows.ApplicationModel.Store namespace is not supported in Windows desktop applications that use the Desktop Bridge or in apps or games that use a development sandbox in Dev Center (for example, this is the case for any game that integrates with Xbox Live). 这些产品必须使用 Windows.Services.Store 命名空间才能实现应用内购买和试用。These products must use the Windows.Services.Store namespace to implement in-app purchases and trials.

开始使用 CurrentApp 和 CurrentAppSimulator 类Get started with the CurrentApp and CurrentAppSimulator classes

Windows.ApplicationModel.Store 命名空间的主要入口点是 CurrentApp 类。The main entry point to the Windows.ApplicationModel.Store namespace is the CurrentApp class. 此类提供的静态属性和方法可用于获取当前应用及其可用加载项的信息、获取当前应用或其加载项的许可证信息、为当前用户购买应用或加载项以及执行其他任务。This class provides static properties and methods you can use to get info for the current app and its available add-ons, get license info for the current app or its add-ons, purchase an app or add-on for the current user, and perform other tasks.

CurrentApp 类从 Microsoft Store 获取其数据,因此必须拥有一个开发人员帐户,而且必须在 Microsoft Store 中发布应用,才能在你的应用中成功使用此类。The CurrentApp class obtains its data from the Microsoft Store, so you must have a developer account and the app must be published in the Store before you can successfully use this class in your app. 在将应用提交到 Microsoft Store 之前,可以使用此类的模拟版本(名为 CurrentAppSimulator)测试代码。Before you submit your app to the Store, you can test your code with a simulated version of this class called CurrentAppSimulator. 测试应用后,并将其提交到 Microsoft Store 之前,必须将 CurrentAppSimulator 的实例替换为 CurrentAppAfter you test your app, and before you submit it to the Microsoft Store, you must replace the instances of CurrentAppSimulator with CurrentApp. 如果应用使用 CurrentAppSimulator,则无法通过认证。Your app will fail certification if it uses CurrentAppSimulator.

当使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在本地文件中进行介绍,该文件位于名为 WindowsStoreProxy.xml 的开发计算机上。When the CurrentAppSimulator is used, the initial state of your app's licensing and in-app products is described in a local file on your development computer named WindowsStoreProxy.xml. 有关此文件的详细信息,请参阅将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 一起使用For more information about this file, see Using the WindowsStoreProxy.xml file with CurrentAppSimulator.

有关可使用 CurrentAppCurrentAppSimulator 执行的常见任务的详细信息,请参阅以下文章。For more information about common tasks you can perform using CurrentApp and CurrentAppSimulator, see the following articles.

主题Topic 说明Description
排除或限制试用版中的功能Exclude or limit features in a trial version 如果允许客户在试用期内免费使用你的应用,则可以通过排除或限制试用期内的某些功能,吸引客户升级到完整版应用。If you enable customers to 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.
启用应用内产品购买Enable in-app product purchases 无论你的应用是否免费,你都可以直接从应用中销售内容、其他应用或新的应用功能(例如解锁游戏的下一关)。Whether your app is free or not, you can sell content, other apps, or new app functionality (such as unlocking the next level of a game) from right within the app. 我们在此处显示了如何在应用中启用这些产品。Here we show you how to enable these products in your app.
启用可消费应用内产品购买Enable consumable in-app product purchases 通过应用商店商业平台提供可消费应用内产品(这些项目可以进行购买、使用和再次购买),以便为客户提供强大可靠的购买体验。Offer consumable in-app products—items that can be purchased, used, and purchased again—through the Store commerce platform to provide your customers with a purchase experience that is both robust and reliable. 这对游戏内货币(金子、金币等)等来说尤为有用,可以购买此类货币,然后将其用于购买特定道具。This is especially useful for things like in-game currency (gold, coins, etc.) that can be purchased and then used to purchase specific power-ups.
管理应用内产品的大目录Manage a large catalog of in-app products 如果你的应用提供较大的应用内产品目录,可以选择按照本主题中描述的过程帮助管理你的目录。If your app offers a large in-app product catalog, you can optionally follow the process described in this topic to help manage your catalog.
使用收据验证产品购买Use receipts to verify product purchases 每个促成成功产品购买的 Microsoft Store 交易都可以选择返回交易收据,该收据可向客户提供有关所列产品和货币成本的信息。Each Microsoft Store transaction that results in a successful product purchase can optionally return a transaction receipt that provides information about the listed product and monetary cost to the customer. 有权访问此信息可支持以下方案:你的应用需要验证用户是否购买了你的应用,或者是否已从 Microsoft Store 进行了应用内产品购买。Having access to this information supports scenarios where your app needs to verify that a user purchased your app, or has made in-app product purchases from the Microsoft Store.

将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 一起使用Using the WindowsStoreProxy.xml file with CurrentAppSimulator

当使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在本地文件中进行介绍,该文件位于名为 WindowsStoreProxy.xml 的开发计算机上。When the CurrentAppSimulator is used, the initial state of your app's licensing and in-app products is described in a local file on your development computer named WindowsStoreProxy.xml. 改变应用状态的 CurrentAppSimulator 方法(例如,通过购买许可证或处理应用内购买)仅更新内存中 CurrentAppSimulator 对象的状态。CurrentAppSimulator methods that alter the app's state, for example by buying a license or handling an in-app purchase, only update the state of the CurrentAppSimulator object in memory. WindowsStoreProxy.xml 的内容不会更改。The contents of WindowsStoreProxy.xml are not changed. 当应用再次启动时,许可证状态将还原到 WindowsStoreProxy.xml 中所述的内容。When the app starts again, the license state reverts to what is described in WindowsStoreProxy.xml.

WindowsStoreProxy.xml 文件默认创建在以下位置:%UserProfile%\AppData\Local\Packages\<应用包文件夹>\LocalState\Microsoft\Windows Store\ApiData。A WindowsStoreProxy.xml file is created by default at the following location: %UserProfile%\AppData\Local\Packages\<app package folder>\LocalState\Microsoft\Windows Store\ApiData. 你可以编辑此文件以定义想要模拟 CurrentAppSimulator 属性的场景。You can edit this file to define the scenario that you want to simulate in the CurrentAppSimulator properties.

尽管可以修改此文件中的值,但我们建议创建自己的 WindowsStoreProxy.xml 文件(在 Visual Studio 项目的数据文件夹中)以供 CurrentAppSimulator 改用。Although you can modify the values in this file, we recommend that you create your own WindowsStoreProxy.xml file (in a data folder of your Visual Studio project) for CurrentAppSimulator to use instead. 模拟交易时,调用 ReloadSimulatorAsync 以加载文件。When simulating the transaction, call ReloadSimulatorAsync to load your file. 如果不调用 ReloadSimulatorAsync 加载你自己的 WindowsStoreProxy.xml 文件, CurrentAppSimulator 将创建/加载(但不是会覆盖)默认 WindowsStoreProxy.xml 文件。If you do not call ReloadSimulatorAsync to load your own WindowsStoreProxy.xml file, CurrentAppSimulator will create/load (but not overwrite) the default WindowsStoreProxy.xml file.

备注

请注意,CurrentAppSimulatorReloadSimulatorAsync 完成之前不会完全初始化。Be aware that CurrentAppSimulator is not fully initialized until ReloadSimulatorAsync completes. 并且,由于 ReloadSimulatorAsync 是异步方法,应格外小心以避免在初始化一个线程时,同时对另一个线程查询 CurrentAppSimulator 会出现争用情况。And, since ReloadSimulatorAsync is an asynchronous method, care should be taken to avoid the race condition of querying CurrentAppSimulator on one thread while it is being initialized on another. 有一种方法是使用一个标志来指示初始化已完成。One technique is to use a flag to indicate that initialization is complete. 从 Microsoft Store 安装的应用必须使用 CurrentApp 而不是 CurrentAppSimulator,并且在这种情况下不调用 ReloadSimulatorAsync,因此刚刚提到的争用情况不适用。An app that is installed from the Microsoft Store must use CurrentApp instead of CurrentAppSimulator, and in that case ReloadSimulatorAsync is not called and therefore the race condition just mentioned does not apply. 出于此原因,请设计你的代码,以便它可在这两种情况下(异步和同步)都起作用。For this reason, design your code so that it will work in both cases, both asychronously and synchronously.

示例Examples

此示例是一个 WindowsStoreProxy.xml 文件(UTF-16 编码),描述了试用模式的应用在 2015 年 1 月 19 日 05:00 (UTC) 过期。This example is a WindowsStoreProxy.xml file (UTF-16 encoded) that describes an app with a trial mode that expires at 05:00 (UTC) on Jan. 19, 2015.

<?xml version="1.0" encoding="UTF-16"?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>2B14D306-D8F8-4066-A45B-0FB3464C67F2</AppId>
      <LinkUri>http://apps.windows.microsoft.com/app/2B14D306-D8F8-4066-A45B-0FB3464C67F2</LinkUri>
      <CurrentMarket>en-US</CurrentMarket>
      <AgeRating>3</AgeRating>
      <MarketData xml:lang="en-us">
        <Name>App with a trial license</Name>
        <Description>Sample app for demonstrating trial license management</Description>
        <Price>4.99</Price>
        <CurrencySymbol>$</CurrencySymbol>
      </MarketData>
    </App>
  </ListingInformation>
  <LicenseInformation>
    <App>
      <IsActive>true</IsActive>
      <IsTrial>true</IsTrial>
      <ExpirationDate>2015-01-19T05:00:00.00Z</ExpirationDate>
    </App>
  </LicenseInformation>
  <Simulation SimulationMode="Automatic">
    <DefaultResponse MethodName="LoadListingInformationAsync_GetResult" HResult="E_FAIL"/>
  </Simulation>
</CurrentApp>

下一个示例是一个 WindowsStoreProxy.xml 文件(UTF-16 编码),描述了应用已购买,但有一项功能在 2015 年 1 月 19 日 05:00 (UTC) 过期,并具有易耗型应用内购买。The next example is a WindowsStoreProxy.xml file (UTF-16 encoded) that describes an app that has been purchased, has a feature that expires at 05:00 (UTC) on Jan. 19, 2015, and has a consumable in-app purchase.

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>988b90e4-5d4d-4dea-99d0-e423e414ffbc</AppId>
      <LinkUri>http://apps.windows.microsoft.com/app/988b90e4-5d4d-4dea-99d0-e423e414ffbc</LinkUri>
      <CurrentMarket>en-us</CurrentMarket>
      <AgeRating>3</AgeRating>
      <MarketData xml:lang="en-us">
        <Name>App with several in-app products</Name>
        <Description>Sample app for demonstrating an expiring in-app product and a consumable in-app product</Description>
        <Price>5.99</Price>
        <CurrencySymbol>$</CurrencySymbol>
      </MarketData>
    </App>
    <Product ProductId="feature1" LicenseDuration="10" ProductType="Durable">
      <MarketData xml:lang="en-us">
        <Name>Expiring Item</Name>
        <Price>1.99</Price>
        <CurrencySymbol>$</CurrencySymbol>
      </MarketData>
    </Product>
    <Product ProductId="consumable1" LicenseDuration="0" ProductType="Consumable">
      <MarketData xml:lang="en-us">
        <Name>Consumable Item</Name>
        <Price>2.99</Price>
        <CurrencySymbol>$</CurrencySymbol>
      </MarketData>
    </Product>
  </ListingInformation>
  <LicenseInformation>
    <App>
      <IsActive>true</IsActive>
      <IsTrial>false</IsTrial>
    </App>
    <Product ProductId="feature1">
      <IsActive>true</IsActive>
      <ExpirationDate>2015-01-19T00:00:00.00Z</ExpirationDate>
    </Product>
  </LicenseInformation>
  <ConsumableInformation>
    <Product ProductId="consumable1" TransactionId="00000001-0000-0000-0000-000000000000" Status="Active"/>
  </ConsumableInformation>
</CurrentApp>

架构Schema

本部分列出的 XSD 文件定义 WindowsStoreProxy.xml 文件的结构。This section lists the XSD file that defines the structure of the WindowsStoreProxy.xml file. 若要在使用 WindowsStoreProxy.xml 文件时将此架构应用到 Visual Studio 中的 XML 编辑器,请执行以下操作:To apply this schema to the XML editor in Visual Studio when working with your WindowsStoreProxy.xml file, do the following:

  1. 在 Visual Studio 中打开 WindowsStoreProxy.xml 文件。Open the WindowsStoreProxy.xml file in Visual Studio.
  2. XML菜单上,单击创建架构On the XML menu, click Create Schema. 这将基于 XML 文件的内容创建一个临时 WindowsStoreProxy.xsd 文件。This will create a temporary WindowsStoreProxy.xsd file based on the contents of the XML file.
  3. 将该 .xsd 文件的内容替换为以下架构。Replace the contents of that .xsd file with the schema below.
  4. 将文件保存到可以将其应用到多个应用项目的位置。Save the file to a location where you can apply it to multiple app projects.
  5. 在 Visual Studio 中切换到 WindowsStoreProxy.xml 文件。Switch to your WindowsStoreProxy.xml file in Visual Studio.
  6. XML菜单上,单击架构,然后在列表中找到 WindowsStoreProxy.xsd 文件所在的行。On the XML menu, click Schemas, then locate the row in the list for the WindowsStoreProxy.xsd file. 如果该文件的位置不是你需要的(例如,如果仍然显示临时文件),则单击添加If the location for the file is not the one you want (for example, if the temporary file is still shown), click Add. 导航到正确的文件,然后单击确定Navigate to the right file, then click OK. 你现在应该可以在列表中看到该文件。You should now see that file in the list. 确保在该架构的使用列中出现复选标记。Make sure a checkmark appears in the Use column for that schema.

一旦完成这些操作,对 WindowsStoreProxy.xml 进行的编辑将遵循该架构。Once you've done this, edits you make to WindowsStoreProxy.xml will be subject to the schema. 有关详细信息,请参阅如何:选择要使用的 XML 架构For more information, see How to: Select the XML Schemas to Use.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
  <xs:element name="CurrentApp" type="CurrentAppDefinition"></xs:element>
  <xs:complexType name="CurrentAppDefinition">
    <xs:sequence>
      <xs:element name="ListingInformation" type="ListingDefinition" minOccurs="1" maxOccurs="1"/>
      <xs:element name="LicenseInformation" type="LicenseDefinition" minOccurs="1" maxOccurs="1"/>
      <xs:element name="ConsumableInformation" type="ConsumableDefinition" minOccurs="0" maxOccurs="1"/>
      <xs:element name="Simulation" type="SimulationDefinition" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="ResponseCodes">
    <xs:restriction base="xs:string">
      <xs:enumeration value="S_OK">
        <xs:annotation>
          <xs:documentation>0x00000000</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="E_INVALIDARG">
        <xs:annotation>
          <xs:documentation>0x80070057</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="E_CANCELLED">
        <xs:annotation>
          <xs:documentation>0x800704C7</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="E_FAIL">
        <xs:annotation>
          <xs:documentation>0x80004005</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="E_OUTOFMEMORY">
        <xs:annotation>
          <xs:documentation>0x8007000E</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="ERROR_ALREADY_EXISTS">
        <xs:annotation>
          <xs:documentation>0x800700B7</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="ConsumableStatus">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Active"/>
      <xs:enumeration value="PurchaseReverted"/>
      <xs:enumeration value="PurchasePending"/>
      <xs:enumeration value="ServerError"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="StoreMethodName">
    <xs:restriction base="xs:string">
      <xs:enumeration value="RequestAppPurchaseAsync_GetResult" id="RPPA"/>
      <xs:enumeration value="RequestProductPurchaseAsync_GetResult" id="RFPA"/>
      <xs:enumeration value="LoadListingInformationAsync_GetResult" id="LLIA"/>
      <xs:enumeration value="ReportConsumableFulfillmentAsync_GetResult" id="RPFA"/>
      <xs:enumeration value="LoadListingInformationByKeywordsAsync_GetResult" id="LLIKA"/>
      <xs:enumeration value="LoadListingInformationByProductIdAsync_GetResult" id="LLIPA"/>
      <xs:enumeration value="GetUnfulfilledConsumablesAsync_GetResult" id="GUC"/>
      <xs:enumeration value="GetAppReceiptAsync_GetResult" id="GARA"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="SimulationMode">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Interactive"/>
      <xs:enumeration value="Automatic"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="ListingDefinition">
    <xs:sequence>
      <xs:element name="App" type="AppListingDefinition"/>
      <xs:element name="Product" type="ProductListingDefinition" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ConsumableDefinition">
    <xs:sequence>
      <xs:element name="Product" type="ConsumableProductDefinition" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="AppListingDefinition">
    <xs:sequence>
      <xs:element name="AppId" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="LinkUri" type="xs:anyURI" minOccurs="1" maxOccurs="1"/>
      <xs:element name="CurrentMarket" type="xs:language" minOccurs="1" maxOccurs="1"/>
      <xs:element name="AgeRating" type="xs:unsignedInt" minOccurs="1" maxOccurs="1"/>
      <xs:element name="MarketData" type="MarketSpecificAppData" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="MarketSpecificAppData">
    <xs:sequence>
      <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="Description" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="Price" type="xs:float" minOccurs="1" maxOccurs="1"/>
      <xs:element name="CurrencySymbol" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="CurrencyCode" type="xs:string" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute ref="xml:lang" use="required"/>
  </xs:complexType>
  <xs:complexType name="MarketSpecificProductData">
    <xs:sequence>
      <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="Price" type="xs:float" minOccurs="1" maxOccurs="1"/>
      <xs:element name="CurrencySymbol" type="xs:string" minOccurs="1" maxOccurs="1"/>
      <xs:element name="CurrencyCode" type="xs:string" minOccurs="0" maxOccurs="1"/>
      <xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
      <xs:element name="Tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
      <xs:element name="Keywords" type="KeywordDefinition" minOccurs="0" maxOccurs="1"/>
      <xs:element name="ImageUri" type="xs:anyURI" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute ref="xml:lang" use="required"/>
  </xs:complexType>
  <xs:complexType name="ProductListingDefinition">
    <xs:sequence>
      <xs:element name="MarketData" type="MarketSpecificProductData" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="ProductId" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:maxLength value="100"/>
          <xs:pattern value="[^,]*"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="LicenseDuration" type="xs:integer" use="optional"/>
    <xs:attribute name="ProductType" type="xs:string" use="optional"/>
  </xs:complexType>
  <xs:simpleType name="guid">
    <xs:restriction base="xs:string">
      <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="ConsumableProductDefinition">
    <xs:attribute name="ProductId" use="required">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:maxLength value="100"/>
          <xs:pattern value="[^,]*"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="TransactionId" type="guid" use="required"/>
    <xs:attribute name="Status" type="ConsumableStatus" use="required"/>
    <xs:attribute name="OfferId" type="xs:string" use="optional"/>
  </xs:complexType>
  <xs:complexType name="LicenseDefinition">
    <xs:sequence>
      <xs:element name="App" type="AppLicenseDefinition"/>
      <xs:element name="Product" type="ProductLicenseDefinition" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="AppLicenseDefinition">
    <xs:sequence>
      <xs:element name="IsActive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
      <xs:element name="IsTrial" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
      <xs:element name="ExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProductLicenseDefinition">
    <xs:sequence>
      <xs:element name="IsActive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
      <xs:element name="ExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="ProductId" type="xs:string" use="required"/>
    <xs:attribute name="OfferId" type="xs:string" use="optional"/>
  </xs:complexType>
  <xs:complexType name="SimulationDefinition" >
    <xs:sequence>
      <xs:element name="DefaultResponse" type="DefaultResponseDefinition" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="SimulationMode" type="SimulationMode" use="optional"/>
  </xs:complexType>
  <xs:complexType name="DefaultResponseDefinition">
    <xs:attribute name="MethodName" type="StoreMethodName" use="required"/>
    <xs:attribute name="HResult" type="ResponseCodes" use="required"/>
  </xs:complexType>
  <xs:complexType name="KeywordDefinition">
    <xs:sequence>
      <xs:element name="Keyword" type="xs:string" minOccurs="0" maxOccurs="10"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

元素和属性说明Element and attribute descriptions

本部分介绍 WindowsStoreProxy.xml 文件中的元素和属性。This section describes the elements and attributes in the WindowsStoreProxy.xml file.

此文件的根元素是 CurrentApp 元素,它表示当前应用。The root element of this file is the CurrentApp element, which represents the current app. 此元素包含以下子元素。This element contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
ListingInformationListingInformation Yes 11 包含应用列表的数据。Contains data from the app's listing.
LicenseInformationLicenseInformation Yes 11 描述了可用于此应用及其持久型加载项的许可证。Describes the licenses available for this app and its durable add-ons.
ConsumableInformationConsumableInformation No 0 或 10 or 1 描述了可用于此应用的易耗型加载项。Describes the consumable add-ons that are available for this app.
模拟Simulation No 0 或 10 or 1 描述了对各种 CurrentAppSimulator 方法的调用在测试过程如何在应用中工作。Describes how calls to various CurrentAppSimulator methods will work in the app during testing.

ListingInformation 元素ListingInformation element

此元素包含应用列表的数据。This element contains data from the app's listing. ListingInformationCurrentApp 元素的必需子元素。ListingInformation is a required child of the CurrentApp element.

ListingInformation 包含以下子元素。ListingInformation contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
AppApp Yes 11 提供有关应用的数据。Provides data about the app.
ProductProduct No 0 或更多0 or more 描述了该应用的加载项。Describes an add-on for the app.

应用元素(ListingInformation 的子元素)App element (child of ListingInformation)

此元素描述了应用的许可证。This element describes the app's license. AppListingInformation 元素的必需子元素。App is a required child of the ListingInformation element.

App 包含以下子元素。App contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
AppIdAppId Yes 11 识别应用商店中应用的 GUID。The GUID that identifies the app in the Store. 这可以是用于测试的任何 GUID。This can be any GUID for testing.
LinkUriLinkUri Yes 11 应用商店中列表页面的 URI。The URI of the listing page in the store. 这可以是用于测试的任何有效 URI。This can be any valid URI for testing.
CurrentMarketCurrentMarket Yes 11 客户所在的国家/地区。The customer's country/region.
AgeRatingAgeRating Yes 11 一个整数,表示应用的最低年龄分级。An integer that represents the minimum age rating of the app. 该值与提交应用时,在开发人员中心仪表板中指定的值相同。This is the same value you would specify in the Dev Center dashboard when you submit the app. 由应用商店使用的值是:3、7、12 和 16。The values used by the Store are: 3, 7, 12, and 16. 有关这些分级的详细信息,请参阅年龄分级For more info on these ratings, see Age ratings.
MarketDataMarketData Yes 1 或更多1 or more 包含有关给定国家/地区的应用的信息。Contains info about the app for a given country/region. 对于在其中列出了应用的每个国家/地区,必须包含 MarketData 元素。For each country/region in which the app is listed, you must include a MarketData element.

MarketData 元素(App 的子元素)MarketData element (child of App)

此元素提供有关给定国家/地区的应用的信息。This element provides info about the app for a given country/region. 对于在其中列出了应用的每个国家/地区,必须包含 MarketData 元素。For each country/region in which the app is listed, you must include a MarketData element. MarketDataApp 元素的必需子元素。MarketData is a required child of the App element.

MarketData 包含以下子元素。MarketData contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
NameName Yes 11 在此国家/地区中应用的名称。The name of the app in this country/region.
DescriptionDescription Yes 11 在此国家/地区中应用的描述。The description of the app for this country/region.
PricePrice Yes 11 在此国家/地区中应用的价格 。The price of the app in this country/region.
CurrencySymbolCurrencySymbol Yes 11 在此国家/地区使用的货币符号。The currency symbol used in this country/region.
CurrencyCodeCurrencyCode No 0 或 10 or 1 在此国家/地区使用的货币代码。The currency code used in this country/region.

MarketData 具有以下属性。MarketData has the following attributes.

属性Attribute 必需Required 描述Description
xml:langxml:lang Yes 指定市场数据信息适用的国家/地区。Specifies the country/region for which the market data info applies.

Product 元素(ListingInformation 的子元素)Product element (child of ListingInformation)

此元素描述了应用的加载项。This element describes an add-on for the app. ProductListingInformation 元素的可选子元素,它包含一个或多个 MarketData 元素。Product is an optional child of the ListingInformation element, and it contains one or more MarketData elements.

Product 具有以下属性。Product has the following attributes.

属性Attribute 必需Required 描述Description
ProductIdProductId Yes 包含应用用来标识加载项的字符串。Contains the string used by the app to identify the add-on.
LicenseDurationLicenseDuration No 指示已购买商品后,许可证有效的天数。Indicates the number of days for which the license will be valid after the item has been purchased. 由产品购买创建的新许可证的过期日期是购买日期加许可证持续时间。The expiration date of the new license created by a product purchase is the purchase date plus the license duration. 此属性仅在 ProductType 属性是 Durable 时使用;对于易耗型加载项,将忽略此属性。This attribute is used only if the ProductType attribute is Durable; this attribute is ignored for consumable add-ons.
ProductTypeProductType No 包含标识应用内产品的持久性的一个值。Contains a value to identify the persistence of the in-app product. 受支持的值有 Durable(默认值)和 ConsumableThe supported values are Durable (the default) and Consumable. 对于持久类型,其他信息由 LicenseInformation 下的 Product 元素描述;对于易耗类型,其他信息由 ConsumableInformation 下的 Product 元素描述。For durable types, additional information is described by a Product element under LicenseInformation; for consumable types, additional information is described by a Product element under ConsumableInformation.

MarketData 元素(Product 的子元素)MarketData element (child of Product)

此元素提供有关给定国家/地区的加载项的信息。This element provides info about the add-on for a given country/region. 对于在其中列出了加载项的每个国家/地区,必须包含 MarketData 元素。For each country/region in which the add-on is listed, you must include a MarketData element. MarketDataProduct 元素的必需子元素。MarketData is a required child of the Product element.

MarketData 包含以下子元素。MarketData contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
NameName Yes 11 在此国家/地区中加载项的名称。The name of the add-on in this country/region.
PricePrice Yes 11 在此国家/地区中加载项的价格。The price of the add-on in this country/region.
CurrencySymbolCurrencySymbol Yes 11 在此国家/地区使用的货币符号。The currency symbol used in this country/region.
CurrencyCodeCurrencyCode No 0 或 10 or 1 在此国家/地区使用的货币代码。The currency code used in this country/region.
DescriptionDescription No 0 或 10 or 1 在此国家/地区中加载项的描述。The description of the add-on for this country/region.
TagTag No 0 或 10 or 1 加载项的自定义开发人员数据(也称为标记)。The custom developer data (also called tag) for the add-on.
关键字Keywords No 0 或 10 or 1 包含最多 10 个 Keyword 元素,这些元素包含加载项的关键字Contains up to 10 Keyword elements that contain the keywords for the add-on.
ImageUriImageUri No 0 或 10 or 1 加载项列表中图像的 URIThe URI for the image in the add-on's listing.

MarketData 具有以下属性。MarketData has the following attributes.

属性Attribute 必需Required 描述Description
xml:langxml:lang Yes 指定市场数据信息适用的国家/地区。Specifies the country/region for which the market data info applies.

LicenseInformation 元素LicenseInformation element

此元素描述了可用于此应用及其持久型应用内产品的许可证。This element describes the licenses available for this app and its durable in-app products. LicenseInformationCurrentApp 元素的必需子元素。LicenseInformation is a required child of the CurrentApp element.

LicenseInformation 包含以下子元素。LicenseInformation contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
AppApp Yes 11 描述应用的许可证。Describes the app's license.
ProductProduct No 0 或更多0 or more 描述了应用中持久型加载项的许可证状态。Describes the license status of a durable add-on in the app.

下表显示了如何通过组合 AppProduct 元素下的值来模拟某些常见情形。The following table shows how to simulate some common conditions by combining values under the App and Product elements.

要模拟的条件Condition to simulate IsActiveIsActive IsTrialIsTrial ExpirationDateExpirationDate
完全授权Fully licensed truetrue falsefalse 不存在。Absent. 它实际上可能会出现并指定将来的日期,但我们建议你从 XML 文件省略该元素。It actually may be present and specify a future date, but you're advised to omit the element from the XML file. 如果它存在并指定过去的日期,那么 IsActive 将被忽略并为 false。If it is present and specifies a date in the past, then IsActive will be ignored and taken to be false.
在试用期内In trial period truetrue truetrue <将来的日期时间> 此元素必须存在,因为 IsTrial 为 true。<a datetime in the future> This element must be present because IsTrial is true. 你可以访问显示当前协调世界时 (UTC) 的网站,了解要设置的日期时间距离现在多久,以便获取想要的剩余试用期。You can visit a website showing the current Coordinated Universal Time (UTC) to know how far in the future to set this to get the remaining trial period you want.
试用过期Expired trial falsefalse truetrue <过去的日期时间> 此元素必须存在,因为 IsTrial 为 true。<a datetime in the past> This element must be present because IsTrial is true. 你可以访问显示当前协调世界时 (UTC) 的网站,了解“过去”的 UTC 时间。You can visit a website showing the current Coordinated Universal Time (UTC) to know when "the past" is in UTC.
无效Invalid falsefalse falsefalse <任何值或省略><any value or omitted>

App 元素(ListingInformation 的子元素)App element (child of LicenseInformation)

此元素描述了应用的许可证。This element describes the app's license. AppLicenseInformation 元素的必需子元素。App is a required child of the LicenseInformation element.

App 包含以下子元素。App contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
IsActiveIsActive Yes 11 描述了此应用的当前许可证状态。Describes the current license state of this app. true 指示许可证有效。false 指示许可证无效。The value true indicates the license is valid; false indicates an invalid license. 通常此值为 true,无论该应用是否具有试用模式。Normally this value is true, whether the app has a trial mode or not. 将此值设置为 false 来测试你的应用在具有无效许可证时的行为。Set this value to false to test how your app behaves when it has an invalid license.
IsTrialIsTrial Yes 11 描述此应用的当前试用状态。Describes the current trial state of this app. true 指示应用在试用期内使用;false 指示应用不在试用期内,或者因为已购买应用,或者因为试用期已过。The value true indicates the app is being used during the trial period; false indicates the app is not in a trial, either because the app has been purchased or the trial period has expired.
ExpirationDateExpirationDate No 0 或 10 or 1 此应用的过期日期,以协调世界时 (UTC) 表示。The date the trial period for this app expires, in Coordinated Universal Time (UTC). 该日期必须表示为:yyyy-mm-ddThh:mm:ss.ssZ。The date must be expressed as: yyyy-mm-ddThh:mm:ss.ssZ. 例如,2015 年 1 月 19 日 05:00 将被指定为 2015-01-19T05:00:00.00Z。For example, 05:00 on January 19, 2015 would be specified as 2015-01-19T05:00:00.00Z. IsTrialtrue 时,此元素是必需的。This element is required when IsTrial is true. 否则,不是必需的。Otherwise, it is not required.

Product 元素(LicenseInformation 的子元素)Product element (child of LicenseInformation)

此元素描述应用中持久型加载项的许可证状态。This element describes the license status of a durable add-on in the app. ProductLicenseInformation 元素的可选子元素。Product is an optional child of the LicenseInformation element.

Product 包含以下子元素。Product contains the following child elements.

元素Element 必需Required 数量Quantity 描述Description
IsActiveIsActive Yes 11 描述此加载项的当前许可证状态。Describes the current license state of this add-on. true 指示可以使用该加载项;false 指示不能使用或未购买该加载项The value true indicates the add-on can be used; false indicates the add-on cannot be used or has not been purchased
ExpirationDateExpirationDate No 0 或 10 or 1 加载项的过期日期,以协调世界时 (UTC) 表示。The date the add-on expires, in Coordinated Universal Time (UTC). 该日期必须表示为:yyyy-mm-ddThh:mm:ss.ssZ。The date must be expressed as: yyyy-mm-ddThh:mm:ss.ssZ. 例如,2015 年 1 月 19 日 05:00 将被指定为 2015-01-19T05:00:00.00Z。For example, 05:00 on January 19, 2015 would be specified as 2015-01-19T05:00:00.00Z. 如果该元素存在,该加载项将具有一个过期日期。If this element is present, the add-on has an expiration date. 如果不存在,该加载项不会到期。If it's not present, the add-on does not expire.

Product 具有以下属性。Product has the following attributes.

属性Attribute 必需Required 描述Description
ProductIdProductId Yes 包含应用用来标识加载项的字符串。Contains the string used by the app to identify the add-on.
OfferIDOfferId No 包含应用用来标识加载项所属的类别的字符串。Contains the string used by the app to identify the category in which the add-on belongs. 这为大型项目目录提供了支持,如管理应用内产品的大型目录所述。This provides support for large item catalogs, as described in Manage a large catalog of in-app products.

模拟元素Simulation element

此元素描述了在测试过程中对各种 CurrentAppSimulator 方法的调用如何在应用中工作。This element describes how calls to various CurrentAppSimulator methods will work in the app during testing. SimulationCurrentApp 元素的可选子元素,它包含零个或多个 DefaultResponse 元素。Simulation is an optional child of the CurrentApp element, and it contains zero or more DefaultResponse elements.

Simulation 具有以下属性。Simulation has the following attributes.

属性Attribute 必需Required 描述Description
SimulationModeSimulationMode No 值可以是 InteractiveAutomaticValues can be Interactive or Automatic. 当此属性设置为 Automatic 时,这些方法将自动返回指定的 HRESULT 错误代码。When this attribute is set to Automatic, the methods will automatically return the specified HRESULT error codes. 这可运行自动测试用例时使用。This can be used when running automated test cases.

DefaultResponse 元素DefaultResponse element

此元素描述了 CurrentAppSimulator 方法返回的默认错误代码。This element describes the default error code returned by a CurrentAppSimulator method. DefaultResponseSimulation 元素的可选子元素。DefaultResponse is an optional child of the Simulation element.

DefaultResponse 具有以下属性。DefaultResponse has the following attributes.

属性Attribute 必需Required 描述Description
MethodNameMethodName Yes 将此属性分配给为架构中的 StoreMethodName 类型显示的枚举值之一。Assign this attribute to one of the enum values shown for the StoreMethodName type in the schema. 每个枚举值表示 CurrentAppSimulator 方法,你希望在测试期间为其模拟应用中的错误代码返回值。Each of these enum values represents a CurrentAppSimulator method for which you want to simulate an error code return value in your app during testing. 例如,值 RequestAppPurchaseAsync_GetResult 指示你想要模拟 RequestAppPurchaseAsync 方法的错误代码返回值。For example, the value RequestAppPurchaseAsync_GetResult indicates you want to simulate the error code return value of the RequestAppPurchaseAsync method.
HResultHResult Yes 将此属性分配给为架构中的 ResponseCodes 类型显示的枚举值之一。Assign this attribute to one of the enum values shown for the ResponseCodes type in the schema. 每个枚举值表示你希望为方法返回的错误代码,该方法已分配给 DefaultResponse 元素的 MethodName 属性。Each of these enum values represents the error code you want to return for the method that is assigned to the MethodName attribute for this DefaultResponse element.

ConsumableInformation 元素ConsumableInformation element

此元素描述了可用于此应用的易耗型加载项。This element describes the consumable add-ons available for this app. ConsumableInformationCurrentApp 元素的可选子元素,它可以包含零个或多个 Product 元素。ConsumableInformation is an optional child of the CurrentApp element, and it can contain zero or more Product elements.

Product 元素(ConsumableInformation 的子元素)Product element (child of ConsumableInformation)

此元素描述易耗型加载项。This element describes a consumable add-on. ProductConsumableInformation 元素的可选子元素。Product is an optional child of the ConsumableInformation element.

Product 具有以下属性。Product has the following attributes.

属性Attribute 必需Required 描述Description
ProductIdProductId Yes 包含应用用来标识易耗型加载项的字符串。Contains the string used by the app to identify the consumable add-on.
TransactionIdTransactionId Yes 包含在实施过程中应用用于跟踪易耗品购买交易的 GUID(作为字符串)。Contains a GUID (as a string) used by the app to track the purchase transaction of a consumable through the process of fulfillment. 请参阅启用易耗型应用内产品购买See Enable consumable in-app product purchases.
状态Status Yes 包含应用用于指示易耗品的实施状态的字符串。Contains the string used by the app to indicate the fulfillment status of a consumable. 值可以是 ActivePurchaseRevertedPurchasePendingServerErrorValues can be Active, PurchaseReverted, PurchasePending, or ServerError.
OfferIDOfferId No 包含应用用来标识易耗品所属的类别的字符串。Contains the string used by the app to identify the category in which the consumable belongs. 这为大型项目目录提供了支持,如管理应用内产品的大型目录所述。This provides support for large item catalogs, as described in Manage a large catalog of in-app products.