アプリのアタッチについて MSIX パッケージをテストする

この記事では、Azure Virtual Desktop の外部で MSIX パッケージをマウントして、アプリのアタッチについてパッケージをテストする方法について説明します。 アプリのアタッチ用の API は、Windows 11 Enterprise と Windows 10 Enterprise で利用でき。 これらの API は、テストのために Azure Virtual Desktop の外部で使用できますが、Azure Virtual Desktop の外部には MSIX アプリのアタッチまたはアプリのアタッチのための管理プレーンはありません。

MSIX アプリのアタッチとアプリのアタッチについて詳しくは、「Azure Virtual Desktop での MSIX アプリのアタッチとアプリのアタッチ」をご覧ください。

前提条件

この記事で説明されているようにしてパッケージをテストするには、次のものが必要です。

この記事では Azure Virtual Desktop の外部でテストするためのプロセスについて説明するので、Azure Virtual Desktop のデプロイは必要ありません。

Note

Microsoft サポートは、CimDiskImage PowerShell モジュールをサポートしていないため、問題が発生した場合は、モジュールの GitHub リポジトリに要求を送る必要があります。

フェーズ

Azure Virtual Desktop の外部で MSIX パッケージを使用するには、次の順序で実行する必要がある 4 つの異なるフェーズがあります。

  1. 段階
  2. [登録]
  3. 登録解除
  4. ステージング解除

ステージングとステージング解除はマシン レベルの操作ですが、登録と登録解除はユーザー レベルの操作です。 使う必要があるコマンドは、使っている PowerShell のバージョンと、ディスク イメージの形式が CimFSVHDXVHD のいずれであるかによって異なります。

Note

すべての MSIX パッケージには証明書が含まれています。 MSIX パッケージの証明書が環境で信頼されていることは、ユーザーが確認する必要があります。

MSIX パッケージのステージングを準備する

ステージング スクリプトは、MSIX パッケージを受け取るマシンを準備し、関連するパッケージをマシンにマウントします。

お使いの PowerShell のバージョンに関連するタブを選んでください。

PowerShell 6 以降を使ってパッケージをステージングするには、ステージング操作の前に次のコマンドを実行して、Windows ランタイム パッケージの機能を PowerShell に取り込む必要があります。

  1. 管理者として PowerShell プロンプトを開きます。

  2. 次のコマンドを実行し、Windows ランタイム パッケージをダウンロードしてインストールします。 次のコマンドを実行する必要があるのは、コンピューターごとに 1 回のみです。

    #Required for PowerShell 6 and later
    $nuGetPackageName = 'Microsoft.Windows.SDK.NET.Ref'
    Register-PackageSource -Name MyNuGet -Location https://www.nuget.org/api/v2 -ProviderName NuGet
    Find-Package $nuGetPackageName | Install-Package
    
  3. 次に、以下のコマンドを実行して、Windows ランタイム コンポーネントを PowerShell で使用できるようにします。

    #Required for PowerShell 6 and later
    $nuGetPackageName = 'Microsoft.Windows.SDK.NET.Ref'
    $winRT = Get-Package $nuGetPackageName
    $dllWinRT = Get-ChildItem (Split-Path -Parent $winRT.Source) -Recurse -File WinRT.Runtime.dll
    $dllSdkNet = Get-ChildItem (Split-Path -Parent $winRT.Source) -Recurse -File Microsoft.Windows.SDK.NET.dll
    Add-Type -AssemblyName $dllWinRT.FullName
    Add-Type -AssemblyName $dllSdkNet.FullName
    

MSIX パッケージをステージングする

MSIX パッケージをステージングするようにコンピューターを準備したので、ディスク イメージをマウントしてから、MSIX パッケージのステージングを完了する必要があります。

ディスク イメージをマウントする

ディスク イメージをマウントするプロセスは、ディスク イメージの形式として CimFsVHDXVHD のどれを使っているかによって異なります。 お使いの形式に関連するタブを選んでください。

CimFS ディスク イメージをマウントするには:

  1. 同じ PowerShell セッションで、次のコマンドを実行します。

    $diskImage = "<Local or UNC path to the disk image>"
    
    $mount = Mount-CimDiskImage -ImagePath $diskImage -PassThru -NoMountPath
    
    #We can now get the Device Id for the mounted volume, this will be useful for the destage step.
    $deviceId = $mount.DeviceId
    Write-Output $deviceId
    
  2. 変数 $deviceId はそのままにします。 この情報はこの記事の後半で必要になります。

  3. 終えたら、「ディスク イメージのステージングを完了する」に進みます。

ディスク イメージのステージングを完了する

最後に、すべてのイメージ形式で次のコマンドを実行して、ディスク イメージのステージングを完了する必要があります。 このコマンドでは、前のセクションでディスク イメージをマウントしたときに作成した $deviceId 変数を使います。

  1. 同じ PowerShell セッションで、次のコマンドを実行してアプリケーションの情報を取得します。

    $manifest = Get-ChildItem -LiteralPath $deviceId -Recurse -File AppxManifest.xml
    $manifestFolder = $manifest.DirectoryName
    
  2. 次のコマンドを実行し、MSIX パッケージの完全な名前を取得して、変数に格納します。 この変数は、後の手順で必要になります。

    $msixPackageFullName = $manifestFolder.Split('\')[-1]
    Write-Output $msixPackageFullName
    
  3. 次のコマンドを実行して、Package Manager API のマニフェスト フォルダーの絶対 URI を作成します。

    $folderUri = $maniFestFolder.Replace('\\?\','file:\\\')
    $folderAbsoluteUri = ([Uri]$folderUri).AbsoluteUri
    
  4. 絶対 URI を使って次のコマンドを実行して、アプリケーション パッケージをステージングします。

    $asTask = ([System.WindowsRuntimeSystemExtensions].GetMethods() | Where-Object { $_.ToString() -eq 'System.Threading.Tasks.Task`1[TResult] AsTask[TResult,TProgress](Windows.Foundation.IAsyncOperationWithProgress`2[TResult,TProgress])' })[0]
    $asTaskAsyncOperation = $asTask.MakeGenericMethod([Windows.Management.Deployment.DeploymentResult], [Windows.Management.Deployment.DeploymentProgress])
    
    $packageManager = New-Object -TypeName Windows.Management.Deployment.PackageManager
    
    $asyncOperation = $packageManager.StagePackageAsync($folderAbsoluteUri, $null, "StageInPlace")
    
  5. 次のコマンドを実行して、アプリケーション パッケージのステージングの進行状況を監視します。 パッケージのステージングにかかる時間は、そのサイズに依存します。 ステージングが完了すると、$stagingResult 変数の Status プロパティは RanToCompletion になります。

    $stagingResult = $asTaskAsyncOperation.Invoke($null, @($asyncOperation))
    
    while ($stagingResult.Status -eq "WaitingForActivation") {
        Write-Output "Waiting for activation..."
        Start-Sleep -Seconds 5
    }
    
    Write-Output $stagingResult
    

MSI パッケージがステージングされたら、MSIX パッケージを登録できます。

MSIX パッケージを登録する

MSIX パッケージを登録するには、同じ PowerShell セッションで次のコマンドを実行します。 このコマンドでは、前のセクションで作成した $msixPackageFullName 変数を使います。

$manifestPath = Join-Path (Join-Path $Env:ProgramFiles 'WindowsApps') (Join-Path $msixPackageFullName AppxManifest.xml)
Add-AppxPackage -Path $manifestPath -DisableDevelopmentMode -Register

これで、MSIX パッケージが登録されたので、アプリケーションをセッションで使用できます。 これで、テストとトラブルシューティングのためにアプリケーションを開くことができます。 終わったら、MSIX パッケージの登録とステージングを解除する必要があります。

MSIX パッケージの登録を解除する

MSIX パッケージの使用が済んで、削除してもよくなったら、まず登録を解除する必要があります。 MSIX パッケージを登録解除するには、同じ PowerShell セッションで次のコマンドを実行します。 これらのコマンドは、ディスクの DeviceId パラメーターをもう一度取得し、前のセクションで作成した $msixPackageFullName 変数を使ってパッケージを削除します。

$appPath = Join-Path (Join-Path $Env:ProgramFiles 'WindowsApps') $msixPackageFullName
$folderInfo = Get-Item $appPath
$deviceId = '\\?\' + $folderInfo.Target.Split('\')[0] +'\'
Write-Output $deviceId #Save this for later

Remove-AppxPackage $msixPackageFullName -PreserveRoamableApplicationData

MSIX パッケージのステージングを解除する

最後に、MSIX パッケージのステージングを解除するには、ディスク イメージのマウントを解除し、同じ PowerShell セッションで次のコマンドを実行して、パッケージがどのユーザーにももう登録されていないことを確認する必要があります。 このコマンドでは、前のセクションで作成した $msixPackageFullName 変数を使います。

Remove-AppxPackage -AllUsers -Package $msixPackageFullName -ErrorAction SilentlyContinue

ディスク イメージのマウントを解除する

ステージング解除のプロセスを終えるには、ディスクをシステムからマウント解除する必要があります。 使う必要があるコマンドは、ディスク イメージの形式によって異なります。 お使いの形式に関連するタブを選んでください。

CimFS のディスク イメージをマウント解除するには、同じ PowerShell セッションで次のコマンドを実行します。

Dismount-CimDiskImage -DeviceId $deviceId

ディスクのマウント解除が完了すると、MSIX パッケージは安全に削除されています。

MSIX アプリのアタッチ エージェントのシミュレーション スクリプトを設定する

MSIX パッケージをデバイスに自動的に追加して削除する場合は、この記事の PowerShell コマンドを使って、起動、ログオン、ログオフ、シャットダウンの時点で実行されるスクリプトを作成できます。 詳しくは、「グループ ポリシーでの起動、シャットダウン、ログオン、ログオフのスクリプトの使用」をご覧ください。 各フェーズに必要な変数を各スクリプトで使用できることを確認する必要があります。

フェーズごとにスクリプトを作成します。

  • 起動スクリプトは、"ステージング" プロセスを実行します。
  • ログオン スクリプトは、"登録" プロセスを実行します。
  • ログオフ スクリプトは、"登録解除" プロセスを実行します。
  • シャットダウン スクリプトは、"ステージング解除" プロセスを実行します。

Note

タスク スケジューラを使って、ステージング スクリプトを実行できます。 スクリプトを実行するには、タスク トリガーを [When the computer starts] (コンピューターの起動時) に設定し、[Run with highest privileges] (最上位の特権で実行する) を有効にします。

パッケージをオフラインで使用する

インターネットに接続されていないデバイス上のビジネス向け Microsoft Store または教育機関向け Microsoft Store のパッケージを使っている場合、アプリを正常に実行するには、Microsoft Store からパッケージ ライセンスを取得して、デバイス上にインストールする必要があります。 デバイスがオンラインであり、ビジネス向け Microsoft Store に接続できる場合は、必要なライセンスが自動的にダウンロードされますが、オフラインになっている場合はライセンスを手動で設定する必要があります。

ライセンス ファイルをインストールするには、WMI ブリッジプロバイダーで MDM_EnterpriseModernAppManagement_StoreLicenses02_01 クラスを呼び出す PowerShell スクリプトを使う必要があります。

オフラインで使うライセンスを設定する方法を次に示します。

  1. アプリ パッケージ、ライセンス、および必要なフレームワークをビジネス向け Microsoft Store からダウンロードします。 エンコードされたライセンス ファイルとエンコードされていないライセンス ファイルの両方が必要です。 オフライン ライセンスを使うアプリをダウンロードする方法については、「オフライン アプリの配布」をご覧ください。

  2. 管理者として次の PowerShell コマンドを実行します。 ライセンスは、ステージング フェーズの最後でインストールできます。 次の変数を編集する必要があります。

    • $contentID は、エンコードされていないライセンス ファイル (.xml) の ContentID 値です。 ライセンス ファイルは任意のテキスト エディターで開くことができます。

    • $licenseBlob は、エンコードされたライセンス ファイル (.bin) のライセンス BLOB の文字列全体です。 エンコードされたライセンス ファイルは、任意のテキスト エディターで開くことができます。

      $namespaceName = "root\cimv2\mdm\dmmap"
      $className = "MDM_EnterpriseModernAppManagement_StoreLicenses02_01"
      $methodName = "AddLicenseMethod"
      $parentID = "./Vendor/MSFT/EnterpriseModernAppManagement/AppLicenses/StoreLicenses"
      
      #Update $contentID with the ContentID value from the unencoded license file (.xml)
      $contentID = "{'ContentID'_in_unencoded_license_file}"
      
      #Update $licenseBlob with the entire String in the encoded license file (.bin)
      $licenseBlob = "{Entire_String_in_encoded_license_file}"
      
      $session = New-CimSession
      
      #The final string passed into the AddLicenseMethod should be of the form <License Content="encoded license blob" />
      $licenseString = '<License Content='+ '"' + $licenseBlob +'"' + ' />'
      
      $params = New-Object Microsoft.Management.Infrastructure.CimMethodParametersCollection
      $param = [Microsoft.Management.Infrastructure.CimMethodParameter]::Create("param",$licenseString ,"String", "In")
      $params.Add($param)
      
      try
      {
           $instance = New-CimInstance -Namespace $namespaceName -ClassName $className -Property @{ParentID=$parentID;InstanceID=$contentID}
           $session.InvokeMethod($namespaceName, $instance, $methodName, $params)
      }
      catch [Exception]
      {
           Write-Host $_ | Out-String
      }
      

デモ スクリプト

MSIX パッケージのテストの 4 つのステージすべてで使うデモ スクリプトと、それらを使う方法に関する構文のヘルプは、GitHub リポジトリにあります。 これらのスクリプトは、すべてのバージョンの PowerShell とすべての形式のディスク イメージで動作します。

次のステップ

Azure Virtual Desktop での MSIX アプリのアタッチとアプリのアタッチについて確認します。