识别 appx 文件的包名称

识别 appx 文件的包名称

有没有比解压 appx 文件并检查给定场景的文件以获取 appx 文件的完整包名更简单的方法?

我在一台机器上安装特定的appx文件

Add-AppxPackage c:\my_data\Microsoft.NET.CoreRuntime.2.2.appx -ForceUpdateFromAnyVersion

第二次运行时,我得到了预期的错误(从 MSDN 复制,因为我的已经本地化了)

ERROR_PACKAGE_ALREADY_EXISTS
    0x80073CFB  The provided package is already installed, and reinstallation of the package is blocked.
You may get this error if installing a package that is not bitwise identical to the package that is already installed. Note that the digital signature is also part of the package. Hence if a package is rebuilt or resigned, it is no longer bitwise identical to the previously installed package. Two possible options to fix this error are: (1) Increment the version number of the app, then rebuild and resign the package (2) Remove the old package for every user on the system before installing the new package. 

好吧。那我该怎么卸载这个应用呢?通常我们执行以下代码:

$coreFileName = "Microsoft.NET.CoreRuntime.2.2"
Get-AppxPackage | Where { $_.PackageFullName.Contains($coreFileName) } | Remove-AppxPackage

但我会删除更多的我安装的软件包比我安装的要多,因为有两个相同的软件包,它们的区别仅在于平台:

Name                   : Microsoft.NET.CoreRuntime.2.2
Publisher              : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture           : X86
ResourceId             :
Version                : 2.2.27902.3
PackageFullName        : Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x86__8wekyb3d8bbwe
InstallLocation        : C:\Program Files\WindowsApps\Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x86__8wekyb3d8bbwe
IsFramework            : True
PackageFamilyName      : Microsoft.NET.CoreRuntime.2.2_8wekyb3d8bbwe
PublisherId            : 8wekyb3d8bbwe
PackageUserInformation : {S-1-5-21-73586283-1958367476-839522115-408575 [DELEC01\schulz_j]: Installed}
...

Name                   : Microsoft.NET.CoreRuntime.2.2
Publisher              : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture           : X64
ResourceId             :
Version                : 2.2.27902.3
PackageFullName        : Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x64__8wekyb3d8bbwe
InstallLocation        : C:\Program Files\WindowsApps\Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x64__8wekyb3d8bbwe
IsFramework            : True
PackageFamilyName      : Microsoft.NET.CoreRuntime.2.2_8wekyb3d8bbwe
PublisherId            : 8wekyb3d8bbwe
PackageUserInformation : {S-1-5-21-73586283-1958367476-839522115-408575 [DELEC01\schulz_j]: Installed}
...

我应该如何获取真正的包全名,即直接匹配包而不需要事先知道它们的包名是什么?

我希望Get-AppxPackageManifest但它让我失望了

Get-AppxPackageManifest c:\my_data\Microsoft.NET.CoreRuntime.2.2.appx

因为它是空的。


编辑:由于时间匆忙,我没有很好地解释意图。让我更精确一点

我想要安装的潜在 appx 文件名为 Microsoft.NET.CoreRuntime.2.2.appx。从名称我无法推断它是 x86 还是 x64。当我安装此 appx 文件的较新版本时,我需要删除此包,并且仅删除此包。

因此,我正在寻找一种将 Get-AppXPackage 结果与 appx 文件关联起来的方法。

代码

$coreFileName = "Microsoft.NET.CoreRuntime.2.2"
Get-AppxPackage | Where { $_.PackageFullName.Contains($coreFileName) }

返回两个包,x64 和 x86,但由于我只安装appx 文件,我不想卸载包。

这是我被困住的地方。给定上面的文件(不是包名):,c:\my_data\Microsoft.NET.CoreRuntime.2.2.appx我如何获取此 appx 的详细信息文件

一种方法是提取 appx 文件,因为它只是一个 zip,然后检查 AppManifest.xml 文件并查找名称 + 平台并将其关联。

但是由于解压缩、读取 xml、删除 zip 等非常复杂,所以我正在寻找一种更简单的方法来做到这一点。

答案1

PowerShell:从 appx 文件中获取 CPU 位数

以下是一些受 IDERA 启发的 PowerShell从 ZIP 存档中提取特定文件发布和逻辑。您只需将完整路径位置设置为 appx 捆绑文件即可。

本质上这...

  • AppxManifest.xml从指定appx文件中搜索并提取所有文件
  • 搜索提取的AppxManifest.xml文件的 XML 内容
    • 从 XML1Identity它得到的元素2ProcessArchitecture'CPU 架构' 的属性值并将该值保存到变量(即$bitness
  • 最后一步是删除 xml-extraction-created 临时文件夹中的所有文件,然后删除该文件夹

电源外壳

$Path = "C:\Test\UWPTest\AppPackages\UWPTest_1.0.0.0_Debug_Test\Dependencies\x64\Microsoft.NET.CoreRuntime.2.2.appx";
$Filter = "AppxManifest.xml";
$OutPath = "$((Get-Childitem -Path $Path -Directory).Directory.FullName)\ztmp";

Add-Type -AssemblyName System.IO.Compression.FileSystem;

If(!(Test-Path -Path $OutPath)){New-Item -Path $OutPath -ItemType Directory -Force};

([System.IO.Compression.ZipFile]::OpenRead($Path)).Entries | % { Process {
    If($_.FullName -like $Filter){$_ | % {
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$OutPath\$($_.Name)", $true)}
        }
    }};
[System.IO.Compression.ZipFile]::OpenRead($Path).Dispose;

[xml]$xml = Get-Content "$OutPath\AppxManifest.xml";
$bitness = ((Select-Xml -Xml $Xml -XPath "*/*").Node).ProcessorArchitecture;
$bitness;

Remove-Item -Path "$OutPath" -Force -Recurse;

XML 内容示例

在此处输入图片描述

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
   xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
   xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
   IgnorableNamespaces="uap"> 
<Identity Name="Microsoft.NET.CoreRuntime.2.2" 
  ProcessorArchitecture="x64" 
  Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" 
  Version="2.2.27902.3" />
<mp:PhoneIdentity PhoneProductId="7D3B4B8B-CA47-4518-823A-A7793F27DA93" 
  PhonePublisherId="6B151E87-785E-4C4A-AA41-823B05AA9A66" />
<Properties>
  <Framework>true</Framework>
  <DisplayName>Microsoft.NET.CoreRuntime.2.2</DisplayName>
  <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
  <Description>Microsoft .Net Core Runtime Package for Universal Windows Applications</Description>
  <Logo>logo.png</Logo>
</Properties>
<Resources>
  <Resource Language="en-US" />
</Resources>
<Dependencies>
  <TargetDeviceFamily
       Name="Windows.Universal"
       MinVersion="10.0.10049.0"
       MaxVersionTested="10.0.10049.0" />
</Dependencies> 
</Package>

支持资源

答案2

PowerShell:仅删除与 CPU 位数匹配的 appx 包

使用 PowerShell 设置关键字'包名称值'作为大批数据类型变量。循环但*在迭代占位符值之前和之后使用星号通配符"*$_*"。展开到PackageFullName属性并使用+=赋值运算符。

使用此方法,您可以获得一个数组所有匹配的值从您在顶部输入的关键字值$Apps = @("Value"),例如,您剩下如下所示的完整包名称。

Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x86__8wekyb3d8bbwe
Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x64__8wekyb3d8bbwe

然后可以通过管道将这些值传输到| Remove-AppxPackage;以根据需要使用条件逻辑执行删除操作,例如,仅匹配的完整包名称_x64_

Microsoft.NET.CoreRuntime.2.2_2.2.27902.3_x64__8wekyb3d8bbwe

电源外壳

$Bitness = "x64"; ## -- Set value here for what you want to remove
$Apps = @("Microsoft.NET.Native.Framework.2.2");

$base = @();
$Apps | %{
    $base += $base = (Get-AppxPackage -Name "*$_*").PackageFullName;
    };

$base;
$base | % { If($_ -match "_$($Bitness)_"){ $_ | Remove-AppxPackage } };

支持资源

相关内容