1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShellでインストールされたAppxPackageの表示名を取得する

Posted at

PowerShell でインストールされた AppxPackage の表示名を取得するには、以下の2つを試す必要があります。

  • アプリパッケージのマニフェストに記載されている表示名を取得
  • SHLoadIndirectString 関数を通して取得する

方法1: アプリパッケージのマニフェストに記載されている表示名を取得

Framework のみ Get-AppxPackageManifest コマンドレットでは取得できないため、インストール場所にある AppxManifest.xml を直接参照します。

アプリパッケージのマニフェストに記載されている表示名を取得
# Microsoft.LanguageExperiencePackja-JP で検証
(Get-AppxPackage -Name Microsoft.LanguageExperiencePackja-JP | Get-AppxPackageManifest).Package.Applications.Application.VisualElements.DisplayName
# "日本語 ローカル エクスペリエンス パック" と返ってくる

# Framework を除外したらすべての名前を取得できる (一部は SHLoadIndirectString 関数を通す必要がある)
(Get-AppxPackage | Where-Object IsFramework -eq $False) | Select-Object Name, @{Name="DisplayNameFromManifest";Expression={(($_ | Get-AppxPackageManifest).Package.Applications.Application.VisualElements.DisplayName)}}


# Microsoft.VCLibs.140.00 で検証 (Architecture ごとにインストールされるため、X64 のみ取得した)
$ManifestPath = (Join-Path (Get-AppxPackage -Name Microsoft.VCLibs.140.00 | Where-Object Architecture -eq "X64").InstallLocation "AppxManifest.xml")
$Manifest = ([Xml](Get-Content -Path $ManifestPath -Encoding utf8))
$Manifest.Package.Properties.DisplayName
# "Microsoft Visual C++ 2015 UWP Runtime Package" と返ってくる

# Frameworkのみ
(Get-AppxPackage | Where-Object IsFramework) | Select-Object Name, @{Name="DisplayNameFromManifest";Expression={([Xml](Get-Content -Path (Join-Path $_.InstallLocation "AppxManifest.xml") -Encoding utf8)).Package.Properties.DisplayName}}

方法2: SHLoadIndirectString 関数を通して取得する

前者の方法ですと、ms-resource:DisplayNameといったテキストが返ってくることがあります。
これは多言語化されているため、パッケージ リソース インデックス (PRI) から SHLoadIndirectString 関数を通して取得します。

SHLoadIndirectString関数をPowerShellで使用する
Add-Type -AssemblyName System.Runtime.InteropServices

$signature = @"
[DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
public static extern int SHLoadIndirectString(string pszSource, System.Text.StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved); 
"@
$ShellLightweightUtilityFunctions = Add-Type -memberDefinition $signature -name "Win32SHLoadIndirectString" -passThru
[System.Text.StringBuilder]$outBuff = 1024

SHLoadIndirectString 関数でリソースを解析する方法はいくつかあるようですが、容易に取得できるのはパッケージ名とリソースIDの組み合わせです。
HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages のキーに DisplayName が定義されていますが、一部のアプリで取得できない・スタートメニューなどで見る名前が表示されないことがあります。

取得したURIを加工する

ms-resource:DisplayName といったテキストのままでは、一部のアプリで取得することができませんでしたが、ms-resource:Resources/DisplayName のように Resources/ を追加することで取得できるようになります。

# Microsoft.WindowsCamera_2020.504.40.0_x64__8wekyb3d8bbwe で検証
$PackageFullName = "Microsoft.WindowsCamera_2020.504.40.0_x64__8wekyb3d8bbwe"
$Manifest = (Get-AppxPackageManifest -Package $PackageFullName)
# "ms-resource:LensSDK/Resources/AppTitle" と返ってくる
$DisplayName = $Manifest.Package.Applications.Application.VisualElements.DisplayName
If ($ShellLightweightUtilityFunctions::SHLoadIndirectString("@{$PackageFullName`?$DisplayName}", $outBuff ,$outBuff.Capacity, [System.IntPtr]::Zero) -eq 0){
    $outBuff.ToString()
    # "カメラ" と返ってくる
}


# windows.immersivecontrolpanel_10.0.2.1000_neutral_neutral_cw5n1h2txyewy で検証
$PackageFullName = "windows.immersivecontrolpanel_10.0.2.1000_neutral_neutral_cw5n1h2txyewy"
$Manifest = (Get-AppxPackageManifest -Package $PackageFullName)
# "ms-resource:DisplayName" と返ってくる
$DisplayName = $Manifest.Package.Applications.Application.VisualElements.DisplayName
If ($ShellLightweightUtilityFunctions::SHLoadIndirectString("@{$PackageFullName`?$DisplayName}", $outBuff ,$outBuff.Capacity, [System.IntPtr]::Zero) -eq 0){
    $outBuff.ToString()
    # 返ってこない
}
# この場合は Resources/ が必要なパターン
$DisplayName = ((($DisplayName -replace "ms-resource://", "") -replace "ms-resource:/", "") -replace "ms-resource:", "")
If ($ShellLightweightUtilityFunctions::SHLoadIndirectString("@{$PackageFullName`?ms-resource:Resources/$DisplayName}", $outBuff ,$outBuff.Capacity, [System.IntPtr]::Zero) -eq 0){
    $outBuff.ToString()
    # "設定" と返ってくる
}

サンプル

https://github.com/rin309/Scripting/blob/master/System/Get-AppxPackageDisplayName/MainScript.ps1 にあります。

20H1 における実行サンプル

https://github.com/rin309/Scripting/blob/master/System/Get-AppxPackageDisplayName/Sample--Get-AppxPackage.csv
https://github.com/rin309/Scripting/blob/master/System/Get-AppxPackageDisplayName/Sample--Get-AppxProvisionedPackage.csv

備考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?