Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Включите режим розничной демонстрации в вашем приложении Windows, чтобы клиенты, которые пробуют компьютеры и устройства в торговом зале, могли сразу начать работать.
Когда клиенты находятся в розничном магазине, они ожидают, что смогут испытать демонстрационные версии ПК и устройств. Они часто тратят значительную часть времени, развлекаясь с приложениями в рамках розничного демонстрационного интерфейса (RDX).
Вы можете настроить приложение для предоставления различных возможностей в обычном или розничном режиме. Например, если приложение начинается с процесса установки, вы можете пропустить его в розничном режиме и предварительно заполнить приложение примерными данными и настройками по умолчанию, чтобы пользователи могли сразу приступить к его использованию.
С точки зрения наших клиентов, существует только одно приложение. Чтобы помочь клиентам различать два режима, мы рекомендуем, когда ваше приложение находится в розничном режиме, чтобы оно явно отображало слово «Розничная» на строке заголовка или в подходящем месте.
Помимо требований Microsoft Store для приложений, приложения с поддержкой RDX также должны быть совместимы с настройкой, очисткой и обновлением RDX, чтобы гарантировать, что клиенты имеют согласованный положительный опыт в розничном магазине.
Принципы проектирования
Показать свое лучшее. Используйте демонстрационную версию для розничной торговли, чтобы показать, насколько круто ваше приложение. Это, скорее всего, первый раз, когда ваш клиент увидит ваше приложение, так что показать им лучший фрагмент!
Показать быстро. Клиенты могут быть нетерпеливыми. Чем быстрее пользователь может испытать реальную ценность вашего приложения, тем лучше.
Держите историю простой. Демонстрационная версия для магазинов — это краткий обзор ценности вашего приложения.
Сосредоточьтесь на опыте. Предоставьте пользователю время для дайджеста содержимого. Хотя довести их до лучшей части быстро важно, проектирование подходящих пауз может помочь им в полной мере наслаждаться впечатлениями.
Технические требования
Так как приложения с поддержкой RDX предназначены для демонстрации лучших приложений для розничных клиентов, они должны соответствовать техническим требованиям и соблюдать правила конфиденциальности, которые Microsoft Store имеет для всех приложений для розничной демонстрации.
Это можно использовать в качестве контрольного списка, чтобы подготовиться к процессу проверки и обеспечить ясность в процессе тестирования. Обратите внимание, что эти требования должны поддерживаться не только для процесса проверки, но и в течение всего времени существования приложения для демонстрации розничной торговли; До тех пор, пока ваше приложение будет работать на розничных демонстрационных устройствах.
Критические требования
Приложения с поддержкой RDX, которые не соответствуют этим критически важным требованиям, будут удалены со всех демонстрационных устройств розничной торговли как можно скорее.
Не запрашивайте личную информацию (PII). Сюда входят сведения о входе, сведения об учетной записи Майкрософт или контактные данные.
Интерфейс без ошибок. Приложение должно выполняться без ошибок. Кроме того, всплывающие окна или уведомления не должны отображаться покупателям на демонстрационных устройствах розничной торговли. Ошибки отражаются отрицательно на самом приложении, вашей фирме, бренде устройства, бренде устройства, бренде производителя устройства и бренде Майкрософт.
Платные приложения должны иметь пробный режим. Приложение должно быть бесплатным или включить пробный режим. Клиенты не хотят платить за опыт в розничном магазине.
Требования высокого приоритета
Приложения с поддержкой RDX, которые не соответствуют этим высоким приоритетам, необходимо немедленно изучить для исправления. Если немедленное исправление не найдено, это приложение может быть удалено со всех демонстрационных устройств розничной торговли.
Запоминающийся офлайн-опыт. Ваше приложение должно продемонстрировать отличную автономную работу, так как около 50% устройств находятся в автономном режиме в местах розничной торговли. Это гарантирует, что клиенты, взаимодействующие с приложением в автономном режиме, по-прежнему могут иметь значимый и положительный опыт.
Обновленный интерфейс содержимого. Ваше приложение никогда не должно запрашивать обновления при подключении к сети. Если требуется обновление, они должны выполняться в фоновом режиме.
Отсутствие анонимной коммуникации. Так как клиент, использующий демонстрационное устройство розничной торговли, является анонимным пользователем, он не сможет отправлять сообщения или предоставлять доступ к содержимому с устройства.
Обеспечьте согласованный опыт с помощью процесса очистки. Каждый клиент должен иметь тот же опыт, когда они идут на розничное демонстрационное устройство. Приложение должно использовать процесс очистки , чтобы вернуться к одному и тому же состоянию по умолчанию после каждого использования. Мы не хотим, чтобы следующий клиент видел, что предыдущий оставил после себя. Это включает в себя таблицы лидеров, достижения и разблокируемые элементы.
Соответствующее возрасту содержание. Все содержимое приложения должно относиться к категории "Подростки" или ниже. Дополнительные сведения см. в статье "Получение оценки приложения по рейтингу IARC и ESRB".
Требования среднего приоритета
Команда Windows Retail Store может обратиться к разработчикам напрямую, чтобы настроить обсуждение по устранению этих проблем.
Возможность успешного выполнения на нескольких устройствах. Приложения должны работать хорошо на всех устройствах, включая устройства с низкими спецификациями. Если приложение установлено на устройствах, которые не соответствуют минимальным спецификациям, приложение должно четко сообщить пользователю об этом. Минимальные требования к устройству должны быть известны, чтобы приложение всегда могли работать с высокой производительностью.
Соответствие требованиям к размеру приложения розничного магазина. Приложение должно быть меньше 800 МБ. Обратитесь напрямую к команде магазина Windows Retail Store для дальнейшего обсуждения, если ваше приложение с поддержкой RDX не соответствует требованиям к размеру.
API RetailInfo: подготовка кода для демонстрационного режима
ВключенРежимДемонстрации
Свойство IsDemoModeEnabled в классе служебной программы RetailInfo, который входит в класс служебной программы Windows. System.Profile пространство имен в Windows 10 и пакете SDK Windows 11 используется в качестве логического индикатора, чтобы указать путь кода, на котором выполняется приложение, — режим нормальный или режим retail.
using Windows.Storage;
StorageFolder folder = ApplicationData.Current.LocalFolder;
if (Windows.System.Profile.RetailInfo.IsDemoModeEnabled)
{
// Use the demo specific directory
folder = await folder.GetFolderAsync("demo");
}
StorageFile file = await folder.GetFileAsync("hello.txt");
// Now read from file
using namespace Windows::Storage;
StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;
if (Windows::System::Profile::RetailInfo::IsDemoModeEnabled)
{
// Use the demo specific directory
create_task(localFolder->GetFolderAsync("demo").then([this](StorageFolder^ demoFolder)
{
return demoFolder->GetFileAsync("hello.txt");
}).then([this](task<StorageFile^> fileTask)
{
StorageFile^ file = fileTask.get();
});
// Do something with file
}
else
{
create_task(localFolder->GetFileAsync("hello.txt").then([this](StorageFile^ file)
{
// Do something with file
});
}
if (Windows.System.Profile.retailInfo.isDemoModeEnabled) {
console.log("Retail mode is enabled.");
} else {
Console.log("Retail mode is not enabled.");
}
RetailInfo.Properties
Когда IsDemoModeEnabled возвращает значение true, можно запросить набор свойств для устройства с помощью RetailInfo.Properties для создания более настраиваемого демонстрационного интерфейса розничной торговли. К этим свойствам относятся имя производителя, экранизация, память и т. д.
using Windows.UI.Xaml.Controls;
using Windows.System.Profile
TextBlock priceText = new TextBlock();
priceText.Text = RetailInfo.Properties[KnownRetailInfo.Price];
// Assume infoPanel is a StackPanel declared in XAML
this.infoPanel.Children.Add(priceText);
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::System::Profile;
TextBlock ^manufacturerText = ref new TextBlock();
manufacturerText.set_Text(RetailInfo::Properties[KnownRetailInfoProperties::Price]);
// Assume infoPanel is a StackPanel declared in XAML
this->infoPanel->Children->Add(manufacturerText);
var pro = Windows.System.Profile;
console.log(pro.retailInfo.properties[pro.KnownRetailInfoProperties.price);
IDL
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// WindowsRuntimeAPISet
import "oaidl.idl";
import "inspectable.idl";
import "Windows.Foundation.idl";
#include <sdkddkver.h>
namespace Windows.System.Profile
{
runtimeclass RetailInfo;
runtimeclass KnownRetailInfoProperties;
[version(NTDDI_WINTHRESHOLD), uuid(0712C6B8-8B92-4F2A-8499-031F1798D6EF), exclusiveto(RetailInfo)]
[version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
interface IRetailInfoStatics : IInspectable
{
[propget] HRESULT IsDemoModeEnabled([out, retval] boolean *value);
[propget] HRESULT Properties([out, retval, hasvariant] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value);
}
[version(NTDDI_WINTHRESHOLD), uuid(50BA207B-33C4-4A5C-AD8A-CD39F0A9C2E9), exclusiveto(KnownRetailInfoProperties)]
[version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
interface IKnownRetailInfoPropertiesStatics : IInspectable
{
[propget] HRESULT RetailAccessCode([out, retval] HSTRING *value);
[propget] HRESULT ManufacturerName([out, retval] HSTRING *value);
[propget] HRESULT ModelName([out, retval] HSTRING *value);
[propget] HRESULT DisplayModelName([out, retval] HSTRING *value);
[propget] HRESULT Price([out, retval] HSTRING *value);
[propget] HRESULT IsFeatured([out, retval] HSTRING *value);
[propget] HRESULT FormFactor([out, retval] HSTRING *value);
[propget] HRESULT ScreenSize([out, retval] HSTRING *value);
[propget] HRESULT Weight([out, retval] HSTRING *value);
[propget] HRESULT DisplayDescription([out, retval] HSTRING *value);
[propget] HRESULT BatteryLifeDescription([out, retval] HSTRING *value);
[propget] HRESULT ProcessorDescription([out, retval] HSTRING *value);
[propget] HRESULT Memory([out, retval] HSTRING *value);
[propget] HRESULT StorageDescription([out, retval] HSTRING *value);
[propget] HRESULT GraphicsDescription([out, retval] HSTRING *value);
[propget] HRESULT FrontCameraDescription([out, retval] HSTRING *value);
[propget] HRESULT RearCameraDescription([out, retval] HSTRING *value);
[propget] HRESULT HasNfc([out, retval] HSTRING *value);
[propget] HRESULT HasSdSlot([out, retval] HSTRING *value);
[propget] HRESULT HasOpticalDrive([out, retval] HSTRING *value);
[propget] HRESULT IsOfficeInstalled([out, retval] HSTRING *value);
[propget] HRESULT WindowsVersion([out, retval] HSTRING *value);
}
[version(NTDDI_WINTHRESHOLD), static(IRetailInfoStatics, NTDDI_WINTHRESHOLD)]
[version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone), static(IRetailInfoStatics, NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
[threading(both)]
[marshaling_behavior(agile)]
runtimeclass RetailInfo
{
}
[version(NTDDI_WINTHRESHOLD), static(IKnownRetailInfoPropertiesStatics, NTDDI_WINTHRESHOLD)]
[version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone), static(IKnownRetailInfoPropertiesStatics, NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
[threading(both)]
[marshaling_behavior(agile)]
runtimeclass KnownRetailInfoProperties
{
}
}
Процесс очистки
Очистка начинается через две минуты после того, как покупатель перестает взаимодействовать с устройством. Запускается розничная демонстрация, и Windows начинает сбрасывать все образцы данных в контактах, фотографиях и других приложениях. В зависимости от устройства это может занять от 1 до 5 минут, чтобы полностью сбросить все обратно в нормальное состояние. Это гарантирует, что каждый клиент в розничном магазине может пройти к устройству и иметь тот же интерфейс при взаимодействии с устройством.
Шаг 1. Очистка
- Все приложения Win32 и магазин закрыты
- Все файлы в известных папках, таких как изображения, видео, музыка, документы, сохраненныеPictures, CameraRoll, Desktop и Downloads , удаляются
- Неструктурированные и структурированные режимы роуминга удаляются
- Структурированные локальные состояния удаляются
Шаг 2. Настройка
- Для автономных устройств: папки остаются пустыми
- Для онлайн-устройств: демонстрационные ресурсы розничной торговли можно отправить на устройство из Microsoft Store
Хранение данных в сеансах пользователей
Для хранения данных в сеансах пользователей можно хранить сведения в ApplicationData.Current.TemporaryFolder , так как процесс очистки по умолчанию не удаляет данные в этой папке автоматически. Обратите внимание, что данные, хранящиеся с помощью LocalState , удаляются во время процесса очистки.
Настройка процесса очистки
Чтобы настроить процесс очистки, реализуйте Microsoft-RetailDemo-Cleanup службу приложений в приложении.
Сценарии, в которых требуется настраиваемая логика очистки, включают выполнение обширной настройки, скачивание и кэширование данных или нежелание удалять данные LocalState.
Шаг 1. Объявление службы Microsoft-RetailDemo-Cleanup в манифесте приложения.
<Applications>
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="MyCompany.MyApp.RDXCustomCleanupTask">
<uap:AppService Name="Microsoft-RetailDemo-Cleanup" />
</uap:Extension>
</Extensions>
</Application>
</Applications>
Шаг 2: Реализуйте свою пользовательскую логику очистки в функции AppdataCleanup, используя приведенный ниже образец шаблона.
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;
using Windows.Storage;
namespace MyCompany.MyApp
{
public sealed class RDXCustomCleanupTask : IBackgroundTask
{
BackgroundTaskCancellationReason _cancelReason = BackgroundTaskCancellationReason.Abort;
BackgroundTaskDeferral _deferral = null;
IBackgroundTaskInstance _taskInstance = null;
AppServiceConnection _appServiceConnection = null;
const string MessageCommand = "Command";
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get the deferral object from the task instance, and take a reference to the taskInstance;
_deferral = taskInstance.GetDeferral();
_taskInstance = taskInstance;
_taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
AppServiceTriggerDetails appService = _taskInstance.TriggerDetails as AppServiceTriggerDetails;
if ((appService != null) && (appService.Name == "Microsoft-RetailDemo-Cleanup"))
{
_appServiceConnection = appService.AppServiceConnection;
_appServiceConnection.RequestReceived += _appServiceConnection_RequestReceived;
_appServiceConnection.ServiceClosed += _appServiceConnection_ServiceClosed;
}
else
{
_deferral.Complete();
}
}
void _appServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
}
async void _appServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
//Get a deferral because we will be calling async code
AppServiceDeferral requestDeferral = args.GetDeferral();
string command = null;
var returnData = new ValueSet();
try
{
ValueSet message = args.Request.Message;
if (message.ContainsKey(MessageCommand))
{
command = message[MessageCommand] as string;
}
if (command != null)
{
switch (command)
{
case "AppdataCleanup":
{
// Do custom clean up logic here
break;
}
}
}
}
catch (Exception e)
{
}
finally
{
requestDeferral.Complete();
// Also release the task deferral since we only process one request per instance.
_deferral.Complete();
}
}
private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
_cancelReason = reason;
}
}
}