Windows 10 バージョン 1607 以降では、Windows.Services.Store 名前空間の StoreContext クラスのメソッドを使用して、Microsoft Store から現在のアプリのパッケージ更新プログラムをプログラムで確認し、更新されたパッケージをダウンロードしてインストールできます。 また、パートナー センターで必須としてマークしたパッケージを照会し、必須の更新プログラムがインストールされるまでアプリの機能を無効にすることもできます。
Windows 10 バージョン 1803 で導入された追加の StoreContext メソッドを使用すると、パッケージの更新プログラムをサイレント モードでダウンロードしてインストールできます (ユーザーに通知 UI を表示しない)、 オプションのパッケージをアンインストールし、アプリのダウンロードおよびインストール キューのパッケージに関する情報を取得できます。
これらの機能を使用すると、ストア内の最新バージョンのアプリ、オプション パッケージ、および関連サービスを使用して、ユーザーベースを自動的に最新の状態に保つことができます。
ユーザーのアクセス許可を使用してパッケージの更新プログラムをダウンロードしてインストールする
このコード例では、 GetAppAndOptionalStorePackageUpdatesAsync メソッドを使用してストアから利用可能なすべてのパッケージ更新プログラムを検出し、 RequestDownloadAndInstallStorePackageUpdatesAsync メソッドを呼び出して更新プログラムをダウンロードしてインストールする方法を示します。 この方法を使用して更新プログラムをダウンロードしてインストールすると、更新プログラムをダウンロードする前にユーザーのアクセス許可を求めるダイアログが OS に表示されます。
注
これらのメソッドは、アプリ 必須パッケージとオプション パッケージ
このコード例では、次のことを前提としています。
- このコードは 、Page のコンテキストで実行されます。
-
ページには、ダウンロード操作の状態を提供するという名前の
downloadProgressBar
が含まれています。 - このコード ファイルには、
Windows.Services.Store 、Windows.Threading.Tasks 、およびWindows.UI.Popups 名前空間の ステートメントを使用するがあります。 - アプリは、アプリを起動したユーザーのコンテキストでのみ実行されるシングル ユーザー アプリです。 マルチユーザー アプリの場合は、GetForUser メソッドを使用して、GetDefault メソッドではなく StoreContext オブジェクトを取得します。
private StoreContext context = null;
public async Task DownloadAndInstallAllUpdatesAsync()
{
if (context == null)
{
context = StoreContext.GetDefault();
}
// Get the updates that are available.
IReadOnlyList<StorePackageUpdate> updates =
await context.GetAppAndOptionalStorePackageUpdatesAsync();
if (updates.Count > 0)
{
// Alert the user that updates are available and ask for their consent
// to start the updates.
MessageDialog dialog = new MessageDialog(
"Download and install updates now? This may cause the application to exit.", "Download and Install?");
dialog.Commands.Add(new UICommand("Yes"));
dialog.Commands.Add(new UICommand("No"));
IUICommand command = await dialog.ShowAsync();
if (command.Label.Equals("Yes", StringComparison.CurrentCultureIgnoreCase))
{
// Download and install the updates.
IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);
// The Progress async method is called one time for each step in the download
// and installation process for each package in this request.
downloadOperation.Progress = async (asyncInfo, progress) =>
{
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
downloadProgressBar.Value = progress.PackageDownloadProgress;
});
};
StorePackageUpdateResult result = await downloadOperation.AsTask();
}
}
}
注
利用可能なパッケージ更新プログラムのみをダウンロード (ただしインストールしない) するには、 RequestDownloadStorePackageUpdatesAsync メソッドを使用します。
ダウンロードとインストールの進行状況情報を表示する
RequestDownloadStorePackageUpdatesAsync メソッドまたは RequestDownloadAndInstallStorePackageUpdatesAsync メソッドを呼び出すと、この要求の各パッケージのダウンロード (またはダウンロードとインストール) プロセスの各ステップに対して 1 回呼び出される Progress ハンドラーを割り当てることができます。 ハンドラーは、進行状況通知を発生させた更新プログラム パッケージに関する情報を提供する StorePackageUpdateStatus オブジェクトを受け取ります。 前の例では、StorePackageUpdateStatus オブジェクトの PackageDownloadProgress フィールドを使用して、ダウンロードおよびインストール プロセスの進行状況を表示します。
RequestDownloadAndInstallStorePackageUpdatesAsync を呼び出してパッケージの更新プログラムを 1 回の操作でダウンロードしてインストールすると、パッケージのダウンロード プロセス中に PackageDownloadProgress フィールドが 0.0 から 0.8 に増加し、インストール中に 0.8 から 1.0 に増加します。 そのため、カスタム進行状況 UI に表示される割合を PackageDownloadProgress フィールドの値に直接マップすると、パッケージのダウンロードが完了し、OS にインストール ダイアログが表示されるときに、UI に 80% が表示されます。 パッケージをダウンロードしてインストールする準備ができたときにカスタム進行状況 UI に 100% を表示する場合は、 PackageDownloadProgress フィールドが 0.8 に達したときに、コードを変更して進行状況 UI に 100% を割り当てることができます。
パッケージの更新プログラムをサイレント モードでダウンロードしてインストールする
Windows 10 バージョン 1803 以降では、 TrySilentDownloadStorePackageUpdatesAsync メソッドと TrySilentDownloadAndInstallStorePackageUpdatesAsync メソッドを使用して、通知 UI をユーザーに表示せずに、パッケージの更新プログラムをサイレント モードでダウンロードしてインストールできます。 この操作は、ユーザーがストアでアプリの更新設定を 自動的に 有効にしており、ユーザーが従量制課金ネットワークにいない場合にのみ成功します。 これらのメソッドを呼び出す前に、最初に CanSilentlyDownloadStorePackageUpdates プロパティ
このコード例では、
このコード例では、次のことを前提としています。
- このコード ファイルには、
Windows.Services.Store およびSystem.Threading.Tasks 名前空間に対して、 ステートメントを使用するが含まれています。 - アプリは、アプリを起動したユーザーのコンテキストでのみ実行されるシングル ユーザー アプリです。 マルチユーザー アプリの場合は、GetForUser メソッドを使用して、GetDefault メソッドではなく StoreContext オブジェクトを取得します。
注
この例のコードによって呼び出される IsNowAGoodTimeToRestartApp、 RetryDownloadAndInstallLater、 および RetryInstallLater メソッドは、独自のアプリの設計に従って必要に応じて実装されることを意図したプレースホルダー メソッドです。
private StoreContext context = null;
public async Task DownloadAndInstallAllUpdatesInBackgroundAsync()
{
if (context == null)
{
context = StoreContext.GetDefault();
}
// Get the updates that are available.
IReadOnlyList<StorePackageUpdate> storePackageUpdates =
await context.GetAppAndOptionalStorePackageUpdatesAsync();
if (storePackageUpdates.Count > 0)
{
if (!context.CanSilentlyDownloadStorePackageUpdates)
{
return;
}
// Start the silent downloads and wait for the downloads to complete.
StorePackageUpdateResult downloadResult =
await context.TrySilentDownloadStorePackageUpdatesAsync(storePackageUpdates);
switch (downloadResult.OverallState)
{
case StorePackageUpdateState.Completed:
// The download has completed successfully. At this point, confirm whether your app
// can restart now and then install the updates (for example, you might only install
// packages silently if your app has been idle for a certain period of time). The
// IsNowAGoodTimeToRestartApp method is not implemented in this example, you should
// implement it as needed for your own app.
if (IsNowAGoodTimeToRestartApp())
{
await InstallUpdate(storePackageUpdates);
}
else
{
// Retry/reschedule the installation later. The RetryInstallLater method is not
// implemented in this example, you should implement it as needed for your own app.
RetryInstallLater();
return;
}
break;
// If the user cancelled the download or you can't perform the download for some other
// reason (for example, Wi-Fi might have been turned off and the device is now on
// a metered network) try again later. The RetryDownloadAndInstallLater method is not
// implemented in this example, you should implement it as needed for your own app.
case StorePackageUpdateState.Canceled:
case StorePackageUpdateState.ErrorLowBattery:
case StorePackageUpdateState.ErrorWiFiRecommended:
case StorePackageUpdateState.ErrorWiFiRequired:
case StorePackageUpdateState.OtherError:
RetryDownloadAndInstallLater();
return;
default:
break;
}
}
}
private async Task InstallUpdate(IReadOnlyList<StorePackageUpdate> storePackageUpdates)
{
// Start the silent installation of the packages. Because the packages have already
// been downloaded in the previous method, the following line of code just installs
// the downloaded packages.
StorePackageUpdateResult downloadResult =
await context.TrySilentDownloadAndInstallStorePackageUpdatesAsync(storePackageUpdates);
switch (downloadResult.OverallState)
{
// If the user cancelled the installation or you can't perform the installation
// for some other reason, try again later. The RetryInstallLater method is not
// implemented in this example, you should implement it as needed for your own app.
case StorePackageUpdateState.Canceled:
case StorePackageUpdateState.ErrorLowBattery:
case StorePackageUpdateState.OtherError:
RetryInstallLater();
return;
default:
break;
}
}
必須パッケージの更新
Windows 10 バージョン 1607 以降を対象とするアプリのパッケージ申請をパートナー センターで作成する場合は、パッケージを必須の と必須になる日時としてマーク
注
パッケージ更新プログラムの必須の状態は Microsoft によって適用されず、OS は必須のアプリ更新プログラムをインストールする必要があることをユーザーに示す UI を提供しません。 開発者は、必須の設定を使用して、独自のコードで必須のアプリの更新を適用することを目的としています。
パッケージの申請を必須としてマークするには:
- パートナー センター
サインインし、アプリの概要ページに移動します。 - 必須にするパッケージ更新プログラムを含む申請の名前をクリックします。
- 申請の [パッケージ] ページに移動します。 このページの下部にある [ この更新プログラムを必須 にする] を選択し、パッケージの更新が必須になる日時を選択します。 このオプションは、申請内のすべての UWP パッケージに適用されます。
詳細については、「 アプリ パッケージのアップロード」を参照してください。
注
パッケージ フライトを作成する場合は、フライトの [パッケージ] ページで同様の UI を使用して、パッケージを必須としてマークできます。 この場合、必須のパッケージ更新プログラムは、フライト グループの一部であるお客様にのみ適用されます。
必須パッケージのコード例
次のコード例は、更新プログラム パッケージが必須かどうかを判断する方法を示しています。 通常、必須のパッケージ更新プログラムが正常にダウンロードまたはインストールされない場合は、ユーザーのアプリ エクスペリエンスを適切にダウングレードする必要があります。
private StoreContext context = null;
// Downloads and installs package updates in separate steps.
public async Task DownloadAndInstallAllUpdatesAsync()
{
if (context == null)
{
context = StoreContext.GetDefault();
}
// Get the updates that are available.
IReadOnlyList<StorePackageUpdate> updates =
await context.GetAppAndOptionalStorePackageUpdatesAsync();
if (updates.Count != 0)
{
// Download the packages.
bool downloaded = await DownloadPackageUpdatesAsync(updates);
if (downloaded)
{
// Install the packages.
await InstallPackageUpdatesAsync(updates);
}
}
}
// Helper method for downloading package updates.
private async Task<bool> DownloadPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
bool downloadedSuccessfully = false;
IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> downloadOperation =
this.context.RequestDownloadStorePackageUpdatesAsync(updates);
// The Progress async method is called one time for each step in the download process for each
// package in this request.
downloadOperation.Progress = async (asyncInfo, progress) =>
{
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
downloadProgressBar.Value = progress.PackageDownloadProgress;
});
};
StorePackageUpdateResult result = await downloadOperation.AsTask();
switch (result.OverallState)
{
case StorePackageUpdateState.Completed:
downloadedSuccessfully = true;
break;
default:
// Get the failed updates.
var failedUpdates = result.StorePackageUpdateStatuses.Where(
status => status.PackageUpdateState != StorePackageUpdateState.Completed);
// See if any failed updates were mandatory
if (updates.Any(u => u.Mandatory && failedUpdates.Any(
failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
{
// At least one of the updates is mandatory. Perform whatever actions you
// want to take for your app: for example, notify the user and disable
// features in your app.
HandleMandatoryPackageError();
}
break;
}
return downloadedSuccessfully;
}
// Helper method for installing package updates.
private async Task InstallPackageUpdatesAsync(IEnumerable<StorePackageUpdate> updates)
{
IAsyncOperationWithProgress<StorePackageUpdateResult, StorePackageUpdateStatus> installOperation =
this.context.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);
// The package updates were already downloaded separately, so this method skips the download
// operation and only installs the updates; no download progress notifications are provided.
StorePackageUpdateResult result = await installOperation.AsTask();
switch (result.OverallState)
{
case StorePackageUpdateState.Completed:
break;
default:
// Get the failed updates.
var failedUpdates = result.StorePackageUpdateStatuses.Where(
status => status.PackageUpdateState != StorePackageUpdateState.Completed);
// See if any failed updates were mandatory
if (updates.Any(u => u.Mandatory && failedUpdates.Any(failed => failed.PackageFamilyName == u.Package.Id.FamilyName)))
{
// At least one of the updates is mandatory, so tell the user.
HandleMandatoryPackageError();
}
break;
}
}
// Helper method for handling the scenario where a mandatory package update fails to
// download or install. Add code to this method to perform whatever actions you want
// to take, such as notifying the user and disabling features in your app.
private void HandleMandatoryPackageError()
{
}
省略可能なパッケージをアンインストールする
Windows 10 バージョン 1803 以降では、 RequestUninstallStorePackageAsync メソッドまたは RequestUninstallStorePackageByStoreIdAsync メソッドを使用して、現在のアプリの オプション パッケージ (DLC パッケージを含む) をアンインストールできます。 たとえば、オプションのパッケージを使用してインストールされたコンテンツを含むアプリがある場合は、ユーザーがオプションパッケージをアンインストールしてディスク領域を解放できる UI を提供できます。
次のコード例では、RequestUninstallStorePackageAsync
- このコード ファイルには、
Windows.Services.Store およびSystem.Threading.Tasks 名前空間に対して、 ステートメントを使用するが含まれています。 - アプリは、アプリを起動したユーザーのコンテキストでのみ実行されるシングル ユーザー アプリです。 マルチユーザー アプリの場合は、GetForUser メソッドを使用して、GetDefault メソッドではなく StoreContext オブジェクトを取得します。
public async Task UninstallPackage(Windows.ApplicationModel.Package package)
{
if (context == null)
{
context = StoreContext.GetDefault();
}
var storeContext = StoreContext.GetDefault();
IAsyncOperation<StoreUninstallStorePackageResult> uninstallOperation =
storeContext.RequestUninstallStorePackageAsync(package);
// At this point, you can update your app UI to show that the package
// is installing.
uninstallOperation.Completed += (asyncInfo, status) =>
{
StoreUninstallStorePackageResult result = uninstallOperation.GetResults();
switch (result.Status)
{
case StoreUninstallStorePackageStatus.Succeeded:
{
// Update your app UI to show the package as uninstalled.
break;
}
default:
{
// Update your app UI to show that the package uninstall failed.
break;
}
}
};
}
ダウンロード キュー情報を取得する
Windows 10 バージョン 1803 以降では、 GetAssociatedStoreQueueItemsAsync メソッドと GetStoreQueueItemsAsync メソッドを使用して、ストアから現在のダウンロードおよびインストール キューにあるパッケージに関する情報を取得できます。 これらの方法は、ダウンロードとインストールに数時間または数日かかる大きなオプション パッケージ (DLC を含む) がアプリまたはゲームでサポートされており、ダウンロードとインストールプロセスが完了する前に顧客がアプリまたはゲームを終了した場合を適切に処理する場合に便利です。 顧客がアプリまたはゲームを再び起動すると、コードでこれらのメソッドを使用して、ダウンロードおよびインストール キューに残っているパッケージの状態に関する情報を取得して、各パッケージの状態を顧客に表示できます。
次のコード例では、GetAssociatedStoreQueueItemsAsync
- このコード ファイルには、
Windows.Services.Store およびSystem.Threading.Tasks 名前空間に対して、 ステートメントを使用するが含まれています。 - アプリは、アプリを起動したユーザーのコンテキストでのみ実行されるシングル ユーザー アプリです。 マルチユーザー アプリの場合は、GetForUser メソッドを使用して、GetDefault メソッドではなく StoreContext オブジェクトを取得します。
注
この例のコードによって呼び出される MarkUpdateInProgressInUI、 RemoveItemFromUI、 MarkInstallCompleteInUI、 MarkInstallErrorInUI、 および MarkInstallPausedInUI メソッドは、独自のアプリの設計に従って必要に応じて実装されることを意図したプレースホルダー メソッドです。
private StoreContext context = null;
private async Task GetQueuedInstallItemsAndBuildInitialStoreUI()
{
if (context == null)
{
context = StoreContext.GetDefault();
}
// Get the Store packages in the install queue.
IReadOnlyList<StoreQueueItem> storeUpdateItems = await context.GetAssociatedStoreQueueItemsAsync();
foreach (StoreQueueItem storeItem in storeUpdateItems)
{
// In this example we only care about package updates.
if (storeItem.InstallKind != StoreQueueItemKind.Update)
continue;
StoreQueueItemStatus currentStatus = storeItem.GetCurrentStatus();
StoreQueueItemState installState = currentStatus.PackageInstallState;
StoreQueueItemExtendedState extendedInstallState =
currentStatus.PackageInstallExtendedState;
// Handle the StatusChanged event to display current status to the customer.
storeItem.StatusChanged += StoreItem_StatusChanged;
switch (installState)
{
// Download and install are still in progress, so update the status for this
// item and provide the extended state info. The following methods are not
// implemented in this example; you should implement them as needed for your
// app's UI.
case StoreQueueItemState.Active:
MarkUpdateInProgressInUI(storeItem, extendedInstallState);
break;
case StoreQueueItemState.Canceled:
RemoveItemFromUI(storeItem);
break;
case StoreQueueItemState.Completed:
MarkInstallCompleteInUI(storeItem);
break;
case StoreQueueItemState.Error:
MarkInstallErrorInUI(storeItem);
break;
case StoreQueueItemState.Paused:
MarkInstallPausedInUI(storeItem, installState, extendedInstallState);
break;
}
}
}
private void StoreItem_StatusChanged(StoreQueueItem sender, object args)
{
StoreQueueItemStatus currentStatus = sender.GetCurrentStatus();
StoreQueueItemState installState = currentStatus.PackageInstallState;
StoreQueueItemExtendedState extendedInstallState = currentStatus.PackageInstallExtendedState;
switch (installState)
{
// Download and install are still in progress, so update the status for this
// item and provide the extended state info. The following methods are not
// implemented in this example; you should implement them as needed for your
// app's UI.
case StoreQueueItemState.Active:
MarkUpdateInProgressInUI(sender, extendedInstallState);
break;
case StoreQueueItemState.Canceled:
RemoveItemFromUI(sender);
break;
case StoreQueueItemState.Completed:
MarkInstallCompleteInUI(sender);
break;
case StoreQueueItemState.Error:
MarkInstallErrorInUI(sender);
break;
case StoreQueueItemState.Paused:
MarkInstallPausedInUI(sender, installState, extendedInstallState);
break;
}
}