如何从带通配符的字符串中获取 Appx 全名?
How to get Appx full name from a string with wildcard?
在 Powershell 中,此命令 Get-AppxPackage *name*
可以显示包的完整详细信息。是否可以使用任何 Windows API 来获得相同的结果?
我看过这个 and details of all Package Query APIs。但它们都需要完整的包名称或 运行 包进程句柄。这些不适用于通配符字符串。
例如,如果我安装了这个包 Microsoft.WindowsCalculator_8wekyb3d8bbwe
我可以使用 Get-AppxPackage *Calculator*
命令获取详细信息。任何 Windows API 都可以吗?我想避免 system()
或 CreateProcess()
之类的事情。
您可以浏览应用程序文件夹并从 xml 清单文件中获取名称。需要管理员权限才能访问应用程序文件夹。
此示例列出了名称中包含 "xbox" 的所有应用。该逻辑可以很容易地适应 C# 或其他语言。
$appNameFilter = '*xbox*'
[System.Collections.Generic.List[string]]$appList = @()
$apps = Get-ChildItem 'C:\Program Files\WindowsApps' -Recurse -Filter 'AppxManifest.xml'
foreach( $app in $apps ) {
$xml = [xml](Get-Content $app.FullName)
$appName = $xml.Package.Properties.DisplayName
if( $appName -like $appNameFilter -and !$appList.Contains( $appName )) {
$appList.Add( $appName )
}
}
$appList
感谢@f6a4 的回答。我采取了相反的方式来实现我的目标。这是我的程序:
我找到一个 answer 来查找 Powershell 中 Get-AppxPacage
cmdlet 后面的 DLL。使用此命令(Get-Command Get-AppxPackage).dll
,Powershell 显示 DLL 文件路径如下:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Windows.Appx.PackageManager.Commands\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.Windows.Appx.PackageManager.Commands.dll
在文件资源管理器中转到该路径并在任何 .NET 反编译器中打开 Microsoft.Windows.Appx.PackageManager.Commands.dll
文件。这里我使用了dnSpy。 Get-AppxManifest
命令部分具有此 C# 代码:
protected override void ProcessRecord()
{
AppxPackage appxPackage = this.packageManager.FindPackage(this.Package);
if (appxPackage != null)
{
string str;
if (appxPackage.IsBundle)
{
str = "\AppxMetadata\AppxBundleManifest.xml";
}
else
{
str = "\AppxManifest.xml";
}
using (FileStream fileStream = new FileStream(appxPackage.InstallLocation + str, FileMode.Open, FileAccess.Read))
{
using (XmlReader xmlReader = XmlReader.Create(fileStream, new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Ignore
}))
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
base.WriteObject(xmlDocument);
}
}
}
}
我将该代码转换为与 Windows API 类似的 C 代码。这是代码片段:
ExpandEnvironmentStringsW(L"%ProgramFiles%\WindowsApps", Buffer, MAX_PATH);
swprintf(FirstFile, MAX_PATH, L"%ls\*", Buffer);
hFile = FindFirstFileW(FirstFile, &fileInfo);
if (hFile != INVALID_HANDLE_VALUE) {
do {
if (wcsstr(fileInfo.cFileName, AppxName) != 0) {
memcpy(PackageName, fileInfo.cFileName, MAX_PATH);
}
} while (FindNextFileW(hFile, &fileInfo) != 0);
}
在 Powershell 中,此命令 Get-AppxPackage *name*
可以显示包的完整详细信息。是否可以使用任何 Windows API 来获得相同的结果?
我看过这个
例如,如果我安装了这个包 Microsoft.WindowsCalculator_8wekyb3d8bbwe
我可以使用 Get-AppxPackage *Calculator*
命令获取详细信息。任何 Windows API 都可以吗?我想避免 system()
或 CreateProcess()
之类的事情。
您可以浏览应用程序文件夹并从 xml 清单文件中获取名称。需要管理员权限才能访问应用程序文件夹。
此示例列出了名称中包含 "xbox" 的所有应用。该逻辑可以很容易地适应 C# 或其他语言。
$appNameFilter = '*xbox*'
[System.Collections.Generic.List[string]]$appList = @()
$apps = Get-ChildItem 'C:\Program Files\WindowsApps' -Recurse -Filter 'AppxManifest.xml'
foreach( $app in $apps ) {
$xml = [xml](Get-Content $app.FullName)
$appName = $xml.Package.Properties.DisplayName
if( $appName -like $appNameFilter -and !$appList.Contains( $appName )) {
$appList.Add( $appName )
}
}
$appList
感谢@f6a4 的回答。我采取了相反的方式来实现我的目标。这是我的程序:
我找到一个 answer 来查找 Powershell 中 Get-AppxPacage
cmdlet 后面的 DLL。使用此命令(Get-Command Get-AppxPackage).dll
,Powershell 显示 DLL 文件路径如下:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Windows.Appx.PackageManager.Commands\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.Windows.Appx.PackageManager.Commands.dll
在文件资源管理器中转到该路径并在任何 .NET 反编译器中打开 Microsoft.Windows.Appx.PackageManager.Commands.dll
文件。这里我使用了dnSpy。 Get-AppxManifest
命令部分具有此 C# 代码:
protected override void ProcessRecord()
{
AppxPackage appxPackage = this.packageManager.FindPackage(this.Package);
if (appxPackage != null)
{
string str;
if (appxPackage.IsBundle)
{
str = "\AppxMetadata\AppxBundleManifest.xml";
}
else
{
str = "\AppxManifest.xml";
}
using (FileStream fileStream = new FileStream(appxPackage.InstallLocation + str, FileMode.Open, FileAccess.Read))
{
using (XmlReader xmlReader = XmlReader.Create(fileStream, new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Ignore
}))
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
base.WriteObject(xmlDocument);
}
}
}
}
我将该代码转换为与 Windows API 类似的 C 代码。这是代码片段:
ExpandEnvironmentStringsW(L"%ProgramFiles%\WindowsApps", Buffer, MAX_PATH);
swprintf(FirstFile, MAX_PATH, L"%ls\*", Buffer);
hFile = FindFirstFileW(FirstFile, &fileInfo);
if (hFile != INVALID_HANDLE_VALUE) {
do {
if (wcsstr(fileInfo.cFileName, AppxName) != 0) {
memcpy(PackageName, fileInfo.cFileName, MAX_PATH);
}
} while (FindNextFileW(hFile, &fileInfo) != 0);
}