如何通过PowerShell调用指定UWP应用打开文件并查询适配格式的应用列表
需求背景
我需要弄清文件资源管理器通过右键菜单「打开方式」调用指定程序、尤其是已安装的微软商店UWP(Appx)应用打开文件的机制,以便通过PowerShell实现该操作。
现有已验证的UWP启动方案仅支持部分应用,比如启动Edge并传入网址的写法如下:
Start-Process ('shell:AppsFolder\' + (Get-AppXPackage *Edge*)[-1].PackageFamilyName + '!App') -ArgumentList 'http://example.org https://wikipedia.org'
但实测「照片」「VLC」这类应用无法直接通过传参打开指定文件,以下写法执行后不会加载目标文件:
Start-Process ('shell:AppsFolder\' + (Get-AppXPackage *Photos*).PackageFamilyName + '!App') -ArgumentList 'C:\test\image1.png'
Start-Process ('shell:AppsFolder\' + (Get-AppXPackage *VLC*).PackageFamilyName + '!App') -ArgumentList 'C:\test\audio1.mp3'
有相关讨论指出该场景可能调用了COM组件:COM: \HKEY_CLASSES_ROOT\jpegfile\ShellEx\{e357fccd-a995-4576-b01f-234630154e96} 及 %SystemRoot%\system32\PhotoMetadataHandler.dll,我对PowerShell/COM/DLL相关技术经验较少,不清楚如何应用上述信息。
咨询问题
- 是否存在通用方案,可通过PowerShell(最坏情况使用C#)调用指定UWP应用打开任意后缀的文件?
- 是否可实现类似文件资源管理器「打开方式」菜单的功能,查询支持指定格式/后缀的应用列表?
解答
问题1:UWP应用打开指定文件的通用方案
存在通用方案,直接调用Windows Runtime提供的Launcher API即可,无需手动处理COM组件调用。该API是系统「打开方式」功能的底层调用接口,兼容所有符合开发规范的UWP应用,PowerShell下可通过内嵌C#调用,示例代码如下:
Add-Type -TypeDefinition @" using System; using System.Threading.Tasks; using Windows.System; using Windows.Storage; using Windows.ApplicationModel; public static class UwpLauncher { public static async Task LaunchFileWithApp(string filePath, string appUserModelId) { StorageFile file = await StorageFile.GetFileFromPathAsync(filePath); LauncherOptions options = new LauncherOptions(); options.TargetApplicationPackageFamilyName = appUserModelId.Split('!')[0]; await Launcher.LaunchFileAsync(file, options); } } "@ -ReferencedAssemblies "Windows.winmd" # 调用示例:用照片应用打开指定图片 $photosAppId = (Get-AppxPackage *Photos*).PackageFamilyName + "!App" [UwpLauncher]::LaunchFileWithApp("C:\test\image1.png", $photosAppId).Wait()
如果不想用WinRT API,也可以直接调用explorer.exe的内置参数实现,写法更简单:
# 格式:explorer.exe shell:AppsFolder\<应用ID> <文件路径> explorer.exe "shell:AppsFolder\$((Get-AppxPackage *Photos*).PackageFamilyName)!App" "C:\test\image1.png"
问题2:查询指定后缀的支持应用列表
可以实现,通过遍历注册表中的文件关联项+UWP应用注册的文件类型声明即可获取完整列表,PowerShell示例代码如下:
function Get-SupportedAppsForExtension { param([string]$Extension) # 先查注册表关联的 ProgID $progId = (Get-ItemProperty "Registry::HKEY_CLASSES_ROOT\$Extension").'(default)' $apps = @() # 查桌面应用关联 Get-ChildItem "Registry::HKEY_CLASSES_ROOT\$progId\shell\*\command" -ErrorAction SilentlyContinue | ForEach-Object { $apps += [PSCustomObject]@{ AppName = $_.PSParentPath.Split('\')[-1] Command = $_.GetValue('') Type = "Desktop" } } # 查UWP应用关联 Get-AppxPackage | ForEach-Object { $manifestPath = "$($_.InstallLocation)\AppxManifest.xml" if (Test-Path $manifestPath) { $manifest = [xml](Get-Content $manifestPath) $fileAssociations = $manifest.Package.Applications.Application.Extensions.Extension | Where-Object { $_.Category -eq "windows.fileTypeAssociation" } if ($fileAssociations.FileTypeAssociation.SupportedFileTypes.FileType | Where-Object { $_.Content -eq $Extension }) { $apps += [PSCustomObject]@{ AppName = $manifest.Package.Properties.DisplayName AppUserModelId = "$($_.PackageFamilyName)!App" Type = "UWP" } } } } return $apps } # 调用示例:查询支持.png格式的应用 Get-SupportedAppsForExtension -Extension ".png"
内容的提问来源于stack exchange,提问作者AlekseyHoffman
相关产品推荐
相关产品推荐

