使用 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 命名空间来实现应用内购买和试用。
CurrentApp 和 CurrentAppSimulator 类入门
Windows.ApplicationModel.Store 命名空间的主要入口点是 CurrentApp 类。 此类提供静态属性和方法,可用于获取当前应用及其可用加载项的信息、获取当前应用或其加载项的许可证信息、为当前用户购买应用或加载项,以及执行其他任务。
CurrentApp 类从 Microsoft Store 获取其数据,因此你必须拥有开发人员帐户,并且应用必须在应用商店中发布,然后才能在应用中成功使用此类。 在将应用提交到应用商店之前,可以使用名为 CurrentAppSimulator 的此类的模拟版本测试代码。 测试应用后,在将其提交到 Microsoft 应用商店之前,必须将 CurrentAppSimulator 的实例替换为 CurrentApp。 如果应用使用 CurrentAppSimulator,则应用将失败认证。
使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在名为 WindowsStoreProxy.xml 的开发计算机上的本地文件中进行了描述。 有关此文件的详细信息,请参阅 将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 配合使用。
有关可以使用 CurrentApp 和 CurrentAppSimulator 执行的常见任务的详细信息,请参阅以下文章。
主题 | 说明 |
---|---|
排除或限制试用版中的功能 | 如果允许客户在试用期内免费使用你的应用,则可以通过排除或限制试用期内的某些功能,吸引客户升级到完整版应用。 |
启用应用内产品购买 | 无论你的应用是否免费,你都可以直接从应用中销售内容、其他应用或新的应用功能(例如解锁游戏的下一关)。 下面我们显示了如何在应用中启用这些产品。 |
启用可消费应用内产品购买 | 通过应用商店商业平台提供可消费应用内产品(这些项目可以进行购买、使用和再次购买),以便为客户提供强大可靠的购买体验。 这对游戏内货币(金子、硬币等)等来说尤为有用,可以购买此类货币,然后将其用于购买特定道具。 |
管理应用内产品的大目录 | 如果你的应用提供较大的应用内产品目录,可以选择按照本主题中描述的过程帮助管理你的目录。 |
使用收据验证产品购买 | 导致产品购买成功的每个Microsoft商店交易都可以选择返回一个交易收据,该收据提供有关列出的产品和货币成本的信息给客户。 访问此信息支持应用需要验证用户是否已购买应用或从 Microsoft 应用商店进行应用内产品购买的方案。 |
将 WindowsStoreProxy.xml 文件与 CurrentAppSimulator 配合使用
使用 CurrentAppSimulator 时,应用许可和应用内产品的初始状态在名为 WindowsStoreProxy.xml 的开发计算机上的本地文件中进行了描述。 用于更改应用状态的 CurrentAppSimulator 方法,例如,通过购买许可证或处理应用内购买,只会更新内存中 CurrentAppSimulator 对象的状态。 不会更改WindowsStoreProxy.xml的内容。 当应用再次启动时,许可证状态将还原为WindowsStoreProxy.xml中所述的内容。
WindowsStoreProxy.xml 文件默认创建在以下位置:%UserProfile%\AppData\Local\Packages\<应用包文件夹>\LocalState\Microsoft\Windows Store\ApiData。 可以编辑此文件以定义要在 CurrentAppSimulator 属性中模拟的方案。
尽管可以修改此文件中的值,但我们建议创建自己的WindowsStoreProxy.xml文件(在 Visual Studio 项目的数据文件夹中),以便 改用 CurrentAppSimulator 。 模拟事务时,调用 ReloadSimulatorAsync 加载文件。 如果不调用 ReloadSimulatorAsync 来加载自己的WindowsStoreProxy.xml文件, CurrentAppSimulator 将创建/加载(但不覆盖)默认WindowsStoreProxy.xml文件。
注意
请注意,在 ReloadSimulatorAsync 完成之前,CurrentAppSimulator 未完全初始化。 而且,由于 ReloadSimulatorAsync 是一种异步方法,因此应注意避免在一个线程上初始化 CurrentAppSimulator 时查询 CurrentAppSimulator 的争用条件。 一种方法是使用标志来指示初始化已完成。 从 Microsoft 应用商店安装的应用必须使用 CurrentApp 而不是 CurrentAppSimulator,在这种情况下,未调用 ReloadSimulatorAsync,因此刚刚提到的争用条件不适用。 出于此原因,请设计你的代码,以便它可在这两种情况下(异步和同步)都起作用。
示例
此示例是一个WindowsStoreProxy.xml文件(UTF-16 编码),用于描述试用模式的应用,该模式将于 2015 年 1 月 19 日 05:00(UTC)过期。
<?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)到期,并具有易耗型应用内购买。
<?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>
架构
本部分列出了定义WindowsStoreProxy.xml文件的结构的 XSD 文件。 若要在处理 WindowsStoreProxy.xml 文件时将此架构应用于 Visual Studio 中的 XML 编辑器,请执行以下操作:
- 在 Visual Studio 中打开WindowsStoreProxy.xml文件。
- 在“XML”菜单上,单击“创建架构”。 这将基于 XML 文件的内容创建一个临时 WindowsStoreProxy.xsd 文件。
- 将 .xsd 文件的内容替换为下面的架构。
- 将文件保存到可将其应用到多个应用项目的位置。
- 切换到 Visual Studio 中的WindowsStoreProxy.xml文件。
- 在“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 元素,它表示当前应用。 此元素包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
ListingInformation | 是 | 1 | 包含应用列表中的数据。 |
LicenseInformation | 是 | 1 | 介绍此应用及其持久加载项可用的许可证。 |
ConsumableInformation | 否 | 0 或 1 | 介绍可用于此应用的易耗型加载项。 |
模拟 | 否 | 0 或 1 | 描述对各种 CurrentAppSimulator 方法的调用如何在测试期间在应用中工作。 |
ListingInformation 元素
此元素包含应用列表中的数据。 ListingInformation 是 CurrentApp 元素的必需子级。
ListingInformation 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
应用 | 是 | 1 | 提供有关应用的数据。 |
Product | 否 | 0 或更多 | 描述应用的加载项。 |
App 元素(ListingInformation 的子级)
此元素描述应用的许可证。 应用是 ListingInformation 元素的必需子元素。
应用 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
AppId | 是 | 1 | 标识应用商店中的应用的 GUID。 这可以是用于测试的任何 GUID。 |
LinkUri | 是 | 1 | 应用商店中列表页的 URI。 这可以是用于测试的任何有效 URI。 |
CurrentMarket | 是 | 1 | 客户的国家/地区。 |
AgeRating | 是 | 1 | 一个整数,表示应用的最小年龄分级。 该值与提交应用时在合作伙伴中心中指定的值相同。 应用商店使用的值为:3、7、12 和 16。 有关这些分级的详细信息,请参阅 年龄分级。 |
MarketData | 是 | 大于等于 1 | 包含有关给定国家/地区应用的信息。 对于列出应用的每个国家/地区,必须包含 MarketData 元素。 |
MarketData 元素 (App 的子级)
此元素提供有关给定国家/地区应用的信息。 对于列出应用的每个国家/地区,必须包含 MarketData 元素。 MarketData 是 App 元素的必需子元素。
MarketData 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
客户 | 是 | 1 | 此国家/地区中的应用的名称。 |
描述 | 是 | 1 | 此国家/地区的应用的说明。 |
价格 | 是 | 1 | 此国家/地区中的应用价格。 |
CurrencySymbol | 是 | 1 | 在此国家/地区中使用的货币符号。 |
CurrencyCode | 否 | 0 或 1 | 在此国家/地区中使用的货币代码。 |
MarketData 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
xml:lang | 是 | 指定应用市场数据信息的国家/地区。 |
Product 元素 (ListingInformation 的子级)
此元素描述应用的加载项。 Product 是 ListingInformation 元素的可选子元素,它包含一个或多个 MarketData 元素。
Product 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
ProductId | 是 | 包含应用用于标识加载项的字符串。 |
LicenseDuration | 否 | 指示在购买商品后许可证有效天数。 产品购买创建的新许可证的到期日期是购买日期和许可证持续时间。 仅当 ProductType 属性为 Durable 时,才使用此属性;对于易耗型加载项,将忽略此属性。 |
ProductType | 否 | 包含用于标识应用内产品的持久性的值。 支持的值为 Durable (默认值)和 易耗品。 对于持久类型,在 LicenseInformation 下的产品元素描述其他信息;对于易耗品类型,易耗品类型下的产品元素将描述其他信息。 |
MarketData 元素 (Product 的子元素)
此元素提供有关给定国家/地区加载项的信息。 对于列出加载项的每个国家/地区,必须包含 MarketData 元素。 MarketData 是 Product 元素的必需子元素。
MarketData 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
客户 | 是 | 1 | 此国家/地区加载项的名称。 |
价格 | 是 | 1 | 此国家/地区加载项的价格。 |
CurrencySymbol | 是 | 1 | 在此国家/地区中使用的货币符号。 |
CurrencyCode | 否 | 0 或 1 | 在此国家/地区中使用的货币代码。 |
描述 | 否 | 0 或 1 | 此国家/地区的加载项的说明。 |
标记 | 否 | 0 或 1 | 加载项的自定义开发人员数据(也称为标记)。 |
关键字 | 否 | 0 或 1 | 包含最多 10 个关键字 元素,其中包含 加载项的 关键字。 |
ImageUri | 否 | 0 或 1 | 加载项列表中映像的 URI。 |
MarketData 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
xml:lang | 是 | 指定应用市场数据信息的国家/地区。 |
LicenseInformation 元素
此元素描述此应用及其持久应用内产品的许可证。 LicenseInformation 是 CurrentApp 元素的必需子级。
LicenseInformation 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
应用 | 是 | 1 | 描述应用的许可证。 |
Product | 否 | 0 或更多 | 描述应用中持久加载项的许可证状态。 |
下表显示如何通过组合 App 和 Product 元素下的值来模拟一些常见条件。
要模拟的条件 | IsActive | IsTrial | ExpirationDate |
---|---|---|---|
完全许可 | true | false | 缺席。 它实际上可能存在并指定将来的日期,但建议省略 XML 文件中的元素。 如果存在并指定过去日期, 则将忽略 IsActive 并将其设置为 false。 |
在试用期内 | 是 | 是 | <将来> 的日期/时间,此元素必须存在,因为 IsTrial 为 true。 你可以访问显示当前协调世界时(UTC)的网站,了解将来要设置该时间以获取所需的剩余试用期。 |
试用期已过期 | false | true | <过去> 此元素的日期时间必须存在,因为 IsTrial 为 true。 可以访问显示当前协调世界时(UTC)的网站,了解“过去”何时采用 UTC。 |
无效 | false | false | <任何值或省略> |
应用元素(LicenseInformation 的子级)
此元素描述应用的许可证。 应用是 LicenseInformation 元素的必需子元素。
应用 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
IsActive | 是 | 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。 IsTrial 为 true 时,此元素是必需的。 否则,不是必需的。 |
Product 元素(LicenseInformation 的子级)
此元素描述应用中持久加载项的许可证状态。 Product 是 LicenseInformation 元素的可选子级。
Product 包含以下子元素。
元素 | 必须 | 数量 | 说明 |
---|---|---|---|
IsActive | 是 | 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 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
ProductId | 是 | 包含应用用于标识加载项的字符串。 |
OfferId | 否 | 包含应用用来标识加载项所属的类别的字符串。 这为大型项目录提供支持,如管理应用内产品的大型目录中所述。 |
Simulation 元素
此元素描述对各种 CurrentAppSimulator 方法的调用如何在测试期间在应用中工作。 模拟是 CurrentApp 元素的可选子元素,它包含零个或多个 DefaultResponse 元素。
模拟 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
SimulationMode | 否 | 值可以是交互式值,也可以是自动值。 当此属性设置为 “自动”时,方法将自动返回指定的 HRESULT 错误代码。 在运行自动测试用例时,可以使用此功能。 |
DefaultResponse 元素
此元素描述 CurrentAppSimulator 方法返回的默认错误代码。 DefaultResponse 是 Simulation 元素的可选子级。
DefaultResponse 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
MethodName | 是 | 将此属性分配给架构中 StoreMethodName 类型显示的枚举值之一。 其中每个枚举值都表示一个 CurrentAppSimulator 方法,你希望在测试期间模拟应用中的错误代码返回值。 例如,值RequestAppPurchaseAsync_GetResult指示要模拟 RequestAppPurchaseAsync 方法的错误代码返回值。 |
HResult | 是 | 将此属性分配给架构中 ResponseCodes 类型显示的枚举值之一。 其中每个枚举值都表示要为分配给此 DefaultResponse 元素的 MethodName 属性的方法返回的错误代码。 |
ConsumableInformation 元素
此元素描述可用于此应用的易耗型加载项。 ConsumableInformation 是 CurrentApp 元素的可选子元素,它可以包含零个或多个 Product 元素。
Product 元素 (ConsumableInformation 的子级)
此元素描述易耗型加载项。 Product 是易耗品信息元素的可选子元素。
Product 具有以下属性。
属性 | 必须 | 说明 |
---|---|---|
ProductId | 是 | 包含应用用于标识易耗型加载项的字符串。 |
TransactionId | 是 | 包含应用用于跟踪通过履行过程中易耗品的购买交易的 GUID(作为字符串)。 请参阅 “启用应用内产品购买”。 |
Status | 是 | 包含应用用来指示易耗品履行状态的字符串。 值可以是 Active、PurchaseReverted、PurchasePending 或 ServerError。 |
OfferId | 否 | 包含应用用来标识易耗品所属类别的字符串。 这为大型项目录提供支持,如管理应用内产品的大型目录中所述。 |