有没有比解压 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 内容
- 从 XML1
Identity
它得到的元素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 } };
支持资源
-
标准别名对于 Foreach 对象:'
%
' 符号,ForEach -
+=
:将变量的值增加指定的值,或将指定值附加到现有值。