使用 Windows.ApplicationModel.Store 命名空间进行应用内购买和试用

可以使用 Windows.ApplicationModel.Store 命名空间中的成员将应用内购买和试用功能添加到通用 Windows 平台(UWP)应用,以帮助实现应用盈利。 这些 API 还提供对应用的许可证信息的访问权限。

本节中的文章提供了深入指导和代码示例,这些指南和代码示例用于在多个常见方案中使用 Windows.ApplicationModel.Store 命名空间中的成员。 有关 UWP 应用中应用内购买相关的基本概念的概述,请参阅 应用内购买和试用。 有关演示如何使用 Windows.ApplicationModel.Store 命名空间实现试用和应用内购买的完整示例,请参阅 应用商店示例

重要

Windows.ApplicationModel.Store 命名空间不再使用新功能进行更新。 如果你的项目面向 Windows 10 周年版(10.0;Visual Studio 中的内部版本 14393 或更高版本(即面向 Windows 10 版本 1607 或更高版本),建议改用 Windows.Services.Store 命名空间。 有关详细信息,请参阅应用内购买和试用。 在 Windows 桌面应用程序中,使用桌面桥或在合作伙伴中心使用开发沙盒的应用或游戏中不支持 Windows.ApplicationModel.Store 命名空间(例如,与 Xbox Live 集成的任何游戏都是这样)。 这些产品必须使用 Windows.Services.Store 命名空间来实现应用内购买和试用。

重要

Windows.ApplicationModel.Store 命名空间中 提供的应用内购买和应用内评分及评审功能目前在提升权限的应用程序中不受支持。

开始对 CurrentApp 和 CurrentAppSimulator 类的初步使用

Windows.ApplicationModel.Store 命名空间的主要入口点是 CurrentApp 类。 此类提供静态属性和方法,可用于获取当前应用及其可用加载项的信息、获取当前应用或其加载项的许可证信息、为当前用户购买应用或加载项,以及执行其他任务。

CurrentApp 类从 Microsoft Store 获取其数据,因此必须具有开发人员帐户,并且应用必须在应用商店中发布,然后才能在应用中成功使用此类。 在将应用提交到应用商店之前,可以使用名为 CurrentAppSimulator 的此类的模拟版本测试代码。 测试应用后,在将其提交到 Microsoft Store 之前,必须将 CurrentAppSimulator 的实例替换为 CurrentApp。 如果应用使用 CurrentAppSimulator,则应用将失败认证。

使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在名为 WindowsStoreProxy.xml的开发计算机上的本地文件中进行描述。 有关此文件的详细信息,请参阅 将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 配合使用

有关可以使用 CurrentApp 和 CurrentAppSimulator 执行的常见任务的详细信息,请参阅以下文章。

主题 Description
排除或限制试用版中的功能 如果允许客户在试用期内免费使用你的应用,则可以通过排除或限制试用期内的某些功能,吸引客户升级到应用的完整版本。
启用应用内产品购买 无论应用是否免费,都可以从应用内直接销售内容、其他应用或新应用功能(例如解锁游戏的下一级别)。 下面介绍如何在应用中启用这些产品。
启用可消费应用内产品购买 通过应用商店商业平台提供可购买、使用和再次购买的易耗型应用内产品,为客户提供可靠可靠的购买体验。 这对于像游戏内货币(黄金、硬币等)这样的元素特别有用,可以购买并用于购买特定的能量提升。
管理应用内产品的大型目录 如果应用提供大型应用内产品目录,可以选择遵循本主题中所述的过程来帮助管理目录。
使用收据验证产品购买 导致产品购买成功的每个Microsoft商店交易都可以选择返回一个交易收据,该收据提供有关列出的产品和货币成本的信息给客户。 访问此信息支持应用需要验证用户是否已购买应用或从 Microsoft 应用商店进行应用内产品购买的方案。

将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 配合使用

使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在名为 WindowsStoreProxy.xml的开发计算机上的本地文件中进行描述。 用于更改应用状态的 CurrentAppSimulator 方法,例如,通过购买许可证或处理应用内购买,只会更新内存中 CurrentAppSimulator 对象的状态。 不会更改 WindowsStoreProxy.xml 的内容。 当应用再次启动时,许可证状态将还原为 WindowsStoreProxy.xml中所述的内容。

默认情况下,WindowsStoreProxy.xml 文件在以下位置创建:%UserProfile%\AppData\Local\Packages\<app package folder>\LocalState\Microsoft\Windows Store\ApiData。 可以编辑此文件以定义要在 CurrentAppSimulator 属性中模拟的方案。

尽管可以修改此文件中的值,但我们建议创建自己的 WindowsStoreProxy.xml 文件(在 Visual Studio 项目的数据文件夹中),以便使用 CurrentAppSimulator 。 模拟事务时,调用 ReloadSimulatorAsync 加载文件。 如果不调用 ReloadSimulatorAsync 来加载自己的 WindowsStoreProxy.xml 文件, CurrentAppSimulator 将创建/加载(但不覆盖)默认 WindowsStoreProxy.xml 文件。

注释

请注意,在 ReloadSimulatorAsync 完成之前,CurrentAppSimulator 未完全初始化。 而且,由于 ReloadSimulatorAsync 是一种异步方法,因此应注意避免在一个线程上初始化 CurrentAppSimulator 的同时,在另一个线程上对其进行查询,以避免产生争用条件。 一种方法是使用标志来指示初始化已完成。 从 Microsoft Store 安装的应用必须使用 CurrentApp 而不是 CurrentAppSimulator,在这种情况下,ReloadSimulatorAsync 未被调用,因此前面提到的竞争条件不适用。 出于此原因,请设计代码,使其在两种情况下都能以异步方式和同步方式工作。

例子

此示例是一个 WindowsStoreProxy.xml 文件(UTF-16 编码),用于描述一个试用模式的应用,该模式将于 2015 年 1 月 19 日 05:00(UTC)过期。

<?xml version="1.0" encoding="UTF-16"?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>00001111-aaaa-2222-bbbb-3333cccc4444</AppId>
      <LinkUri>http://apps.windows.microsoft.com/app/00001111-aaaa-2222-bbbb-3333cccc4444</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)到期,并且应用内购买易耗品。

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>11112222-bbbb-3333-cccc-4444dddd5555</AppId>
      <LinkUri>http://apps.windows.microsoft.com/app/11112222-bbbb-3333-cccc-4444dddd5555</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

本部分列出了定义 WindowsStoreProxy.xml 文件的结构的 XSD 文件。 若要在处理 WindowsStoreProxy.xml 文件时将此架构应用于 Visual Studio 中的 XML 编辑器,请执行以下作:

  1. 在 Visual Studio 中打开 WindowsStoreProxy.xml 文件。
  2. XML 菜单上,单击“ 创建架构”。 这将基于 XML 文件的内容创建一个临时 WindowsStoreProxy.xsd 文件。
  3. 将 .xsd 文件的内容替换为下面的架构。
  4. 将文件保存到可将其应用到多个应用项目的位置。
  5. 在 Visual Studio 中打开您的 WindowsStoreProxy.xml 文件。
  6. XML 菜单上,单击“ 架构”,然后在 WindowsStoreProxy.xsd 文件列表中找到该行。 如果文件的位置不是所需的文件(例如,如果仍显示临时文件),请单击“ 添加”。 导航到正确的文件,然后单击“ 确定”。 现在应该会在列表中看到该文件。 请确保该架构的 “使用 ”列中显示复选标记。

完成此作后,对 WindowsStoreProxy.xml 所做的编辑将受到架构的约束。 有关详细信息,请参阅 如何:选择要使用的 XML 架构

<?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>

元素和属性说明

本部分介绍 WindowsStoreProxy.xml 文件中的元素和属性。

此文件的根元素是 CurrentApp 元素,它表示当前应用。 此元素包含以下子元素。

元素 必选 数量 Description
列表信息 是的 1 包含应用列表中的数据。
LicenseInformation 是的 1 介绍此应用及其持久性插件可用的许可证。
消耗品信息 0 或 1 介绍可用于此应用的易耗型加载项。
模拟 0 或 1 描述对各种 CurrentAppSimulator 方法的调用如何在测试期间在应用中工作。

列表信息元素

此元素包含应用列表中的数据。 ListingInformationCurrentApp 元素的必需子级。

ListingInformation 包含以下子元素。

元素 必选 数量 Description
应用程序 是的 1 提供有关应用的数据。
产品 0 或更多 描述应用程序的加载项。

App 元素(ListingInformation 的子元素)

此元素描述应用的许可证。 应用ListingInformation 元素的必需子元素。

应用 包含以下子元素。

元素 必选 数量 Description
AppId 是的 1 应用商店中标识应用的 GUID。 这可以是任意一个用于测试的GUID。
LinkUri 是的 1 应用商店中列表页的 URI。 这可以是用于测试的任何有效 URI。
CurrentMarket 是的 1 客户的国家/地区。
AgeRating 是的 1 一个整数,表示应用的最小年龄分级。 提交应用时,将在合作伙伴中心指定此值。 应用商店使用的值为:3、7、12 和 16。 有关这些分级的详细信息,请参阅 年龄分级
MarketData 是的 大于等于 1 包含有关给定国家/地区应用的信息。 对于列出应用的每个国家/地区,必须包含 MarketData 元素。

MarketData 元素(App 的子级)

此元素提供有关给定国家/地区应用的信息。 对于列出应用的每个国家/地区,必须包含 MarketData 元素。 MarketDataApp 元素的必需子元素。

MarketData 包含以下子元素。

元素 必选 数量 Description
名称 是的 1 此国家/地区中的应用的名称。
说明 是的 1 该国家/地区的应用程序说明。
价格 是的 1 此国家/地区中的应用价格。
CurrencySymbol 是的 1 在此国家/地区中使用的货币符号。
CurrencyCode 0 或 1 在此国家/地区中使用的货币代码。

MarketData 具有以下属性。

Attribute 必选 Description
xml:lang 是的 指定应用市场数据信息的国家/地区。

Product 元素(ListingInformation 的子节点)

此元素描述应用的加载项。 ProductListingInformation 元素的可选子元素,它包含一个或多个 MarketData 元素。

Product 具有以下属性。

Attribute 必选 Description
ProductId 是的 包含应用用于标识加载项的字符串。
LicenseDuration 指示在购买商品后许可证有效天数。 产品购买创建的新许可证的到期日期是购买日期和许可证持续时间。 仅当 ProductType 属性为 Durable 时,才使用此属性;对于易耗型加载项,忽略此属性。
ProductType 包含用于标识应用内产品的持久性的值。 支持的值为 Durable (默认值)和 易耗品。 对于持久类型,LicenseInformation的产品元素描述了其他信息;对于易耗品类型,在 ConsumableInformation的产品元素描述了其他信息。

MarketData 元素 (Product 的子元素)

此元素提供有关给定国家/地区加载项的信息。 对于列出加载项的每个国家/地区,必须包含 MarketData 元素。 MarketDataProduct 元素的必需子元素。

MarketData 包含以下子元素。

元素 必选 数量 Description
名称 是的 1 此国家/地区加载项的名称。
价格 是的 1 此国家/地区加载项的价格。
CurrencySymbol 是的 1 在此国家/地区中使用的货币符号。
CurrencyCode 0 或 1 在此国家/地区中使用的货币代码。
说明 0 或 1 此国家/地区的加载项的说明。
Tag 0 或 1 加载项的 自定义开发人员数据(也称为标签)。
关键字 0 或 1 包含最多 10 个 关键字 元素,其中包含加载项 的关键字
ImageUri 0 或 1 加载项列表中 映像的 URI

MarketData 具有以下属性。

Attribute 必选 Description
xml:lang 是的 指定应用市场数据信息的国家/地区。

LicenseInformation 元素

此元素描述此应用及其持久应用内产品的许可证。 LicenseInformationCurrentApp 元素的必需子级。

LicenseInformation 包含以下子元素。

元素 必选 数量 Description
应用程序 是的 1 描述应用的许可证。
产品 0 或更多 描述应用中持久加载项的许可证状态。

下表显示如何通过组合 AppProduct 元素下的值来模拟一些常见条件。

要模拟的条件 IsActive IsTrial ExpirationDate
完全授权 缺席。 它实际上可能存在并指定将来的日期,但建议省略 XML 文件中的元素。 如果存在并指定过去日期,则将忽略 IsActive 并将其设置为 false。
在试用期内 <未来的日期时间>,该元素必须存在,因为 IsTrial 为真。 你可以访问显示当前协调世界时(UTC)的网站,了解将来要设置该时间以获取所需的剩余试用期。
试用期已过期 <一个过去的日期时间> 必须存在此元素,因为 IsTrial 为 true。 可以访问显示当前协调世界时(UTC)的网站,了解“过去”何时采用 UTC。
无效 <任何值或省略>

应用元素(LicenseInformation 的子级)

此元素描述应用的许可证。 应用LicenseInformation 元素的必需子元素。

应用 包含以下子元素。

元素 必选 数量 Description
是否激活 是的 1 描述此应用的当前许可证状态。 如果值为 true ,则表示许可证有效; false 表示许可证无效。 通常此值为 true,无论应用是否具有试用模式。 将此值设置为 false ,以测试应用在许可证无效时的行为方式。
IsTrial 是的 1 描述此应用的当前试用状态。 值 true 表示应用在试用期间正在使用; false 表示应用不在试用版中,要么是因为应用已购买或试用期已过期。
ExpirationDate 0 或 1 此应用试用期到期的日期,以协调世界时(UTC)为准。 日期必须表示为:yyyy-mm-ddThh:mm:ss.ssZ。 例如,2015 年 1 月 19 日 05:00 将指定为 2015-01-19T05:00:00.00Z。 IsTrialtrue 时,此元素是必需的。 否则,不是必需的。

产品元素(LicenseInformation 的子级)

此元素描述应用中持久加载项的许可证状态。 ProductLicenseInformation 元素的可选子级。

Product 包含以下子元素。

元素 必选 数量 Description
是否激活 是的 1 描述此加载项的当前许可证状态。 值 true 指示可以使用加载项; false 表示无法使用或尚未购买加载项
ExpirationDate 0 或 1 加载项到期的日期,采用协调世界时(UTC)。 日期必须表示为:yyyy-mm-ddThh:mm:ss.ssZ。 例如,2015 年 1 月 19 日 05:00 将指定为 2015-01-19T05:00:00.00Z。 如果此元素存在,则加载项具有到期日期。 如果不存在,则加载项不会过期。

Product 具有以下属性。

Attribute 必选 Description
ProductId 是的 包含应用用于标识加载项的字符串。
OfferId 包含应用用来标识加载项所属的类别的字符串。 这为大型项目录提供支持,如 管理应用内产品的大型目录中所述。

模拟元素

此元素描述对各种 CurrentAppSimulator 方法的调用如何在测试期间在应用中工作。 模拟CurrentApp 元素的可选子元素,它包含零个或多个 DefaultResponse 元素。

模拟 具有以下属性。

Attribute 必选 Description
SimulationMode 值可以是 交互式 值,也可以是 自动值。 当此属性设置为 “自动”时,方法将自动返回指定的 HRESULT 错误代码。 在运行自动测试用例时,可以使用此功能。

DefaultResponse 元素

此元素描述 CurrentAppSimulator 方法返回的默认错误代码。 DefaultResponseSimulation 元素的可选子级。

DefaultResponse 具有以下属性。

Attribute 必选 Description
MethodName 是的 将此属性分配给架构StoreMethodName 类型显示的枚举值之一。 其中每个枚举值都表示一个 CurrentAppSimulator 方法,你希望在测试期间模拟应用中的错误代码返回值。 例如,值 RequestAppPurchaseAsync_GetResult 指示要模拟 RequestAppPurchaseAsync 方法的错误代码返回值。
[HRESULT] 是的 将此属性分配给架构ResponseCodes 类型显示的枚举值之一。 其中每个枚举值都表示要为分配给此 DefaultResponse 元素的 MethodName 属性的方法返回的错误代码。

ConsumableInformation 元素

此元素描述可用于此应用的易耗型加载项。 ConsumableInformationCurrentApp 元素的可选子元素,它可以包含零个或多个 Product 元素。

产品元素(ConsumableInformation 的子级)

此元素描述易耗型加载项。 Product易耗品信息元素 的可选子元素。

Product 具有以下属性。

Attribute 必选 Description
ProductId 是的 包含应用用于标识消耗型附加组件的字符串。
TransactionId 是的 包含一个 GUID(作为字符串),用于应用程序在整个履行过程中跟踪易耗品的购买交易。 请参阅 “启用应用内产品购买”。
地位 是的 包含应用用来指示易耗品履行状态的字符串。 值可以是 ActivePurchaseRevertedPurchasePendingServerError
OfferId 包含应用用来标识易耗品所属类别的字符串。 这为大型项目录提供支持,如 管理应用内产品的大型目录中所述。