PS:
不使用额外的nuget包或SDK,控制台程序都能用。
首先使用PowerShell通过Get-AppXPackage 获取所有UWP应用信息。
根据应用的PackageFamilyName为参数,调用以下代码,即可获取版本信息
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Management;
namespace ConsoleApp1
{
class Program
{
const uint PACKAGE_INFORMATION_BASIC = 0x00000000;
[DllImport("kernel32.dll", SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
public static extern long GetPackagesByPackageFamily(
string packageFamilyName,
ref uint count,
[Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[] packageFullNames,
ref uint bufferLength,
IntPtr buffer);
[DllImport("kernel32.dll", SetLastError = false, ExactSpelling = true)]
public static extern long PackageIdFromFullName(
[MarshalAs(UnmanagedType.LPWStr)] string packageFullName,
uint flags,
ref uint bufferLength,
IntPtr buffer);
public enum APPX_PACKAGE_ARCHITECTURE
{
/// <summary>The x86 processor architecture.</summary>
APPX_PACKAGE_ARCHITECTURE_X86 = 0,
/// <summary>The ARM processor architecture.</summary>
APPX_PACKAGE_ARCHITECTURE_ARM = 5,
/// <summary>The x64 processor architecture.</summary>
APPX_PACKAGE_ARCHITECTURE_X64 = 9,
/// <summary>Any processor architecture.</summary>
APPX_PACKAGE_ARCHITECTURE_NEUTRAL = 11,
/// <summary>The 64-bit ARM processor architecture.</summary>
APPX_PACKAGE_ARCHITECTURE_ARM64 = 12,
}
//union
[StructLayout(LayoutKind.Explicit)]
public struct PACKAGE_VERSION
{
[FieldOffset(0)]
public ulong Version;
[FieldOffset(0)]
public DUMMYSTRUCTNAME Parts;
public PACKAGE_VERSION(ulong version, DUMMYSTRUCTNAME parts)
{
Version = version;
Parts = parts;
}
public struct DUMMYSTRUCTNAME
{
public ushort Revision;
public ushort Build;
public ushort Minor;
public ushort Major;
public DUMMYSTRUCTNAME(ushort revision, ushort build, ushort minor, ushort major)
{
Revision = revision;
Build = build;
Minor = minor;
Major = major;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PACKAGE_ID
{
public uint reserved;
public APPX_PACKAGE_ARCHITECTURE processorArchitecture;
public PACKAGE_VERSION version;
public string name;
public string publisher;
public string resourceId;
public string publisherId;
public PACKAGE_ID(uint reserved, APPX_PACKAGE_ARCHITECTURE processorArchitecture, PACKAGE_VERSION version, string name, string publisher, string resourceId, string publisherId)
{
this.reserved = reserved;
this.processorArchitecture = processorArchitecture;
this.version = version;
this.name = name;
this.publisher = publisher;
this.resourceId = resourceId;
this.publisherId = publisherId;
}
public override string ToString()
{
return $"{version.Parts.Major}.{version.Parts.Minor}.{version.Parts.Build}.{version.Parts.Revision}";
}
}
public static PACKAGE_ID getUWPVersion(string packageFamilyName)
{
PACKAGE_VERSION pACKAGE_VERSION = new PACKAGE_VERSION(0, new PACKAGE_VERSION.DUMMYSTRUCTNAME(0, 0, 0, 0));
PACKAGE_ID packageId = new PACKAGE_ID(0, APPX_PACKAGE_ARCHITECTURE.APPX_PACKAGE_ARCHITECTURE_X86, pACKAGE_VERSION, "", "", "", "");
uint packageCount = 0;
uint bufferLength = 0;
IntPtr buffer = IntPtr.Zero;
IntPtr pIdBuffer = IntPtr.Zero;
long res2 = GetPackagesByPackageFamily(packageFamilyName, ref packageCount, null, ref bufferLength, IntPtr.Zero);
if (packageCount > 0)
{
string[] packageFullNames = new string[packageCount];
buffer = Marshal.AllocHGlobal((int)bufferLength);
res2 = GetPackagesByPackageFamily(packageFamilyName, ref packageCount, packageFullNames, ref bufferLength, buffer);
uint nFlags = PACKAGE_INFORMATION_BASIC;
string pFirstPackage = packageFullNames[0];
uint nIdLen = 0;
long nRet = PackageIdFromFullName(pFirstPackage, nFlags, ref nIdLen, IntPtr.Zero);
if (nIdLen > 0)
{
pIdBuffer = Marshal.AllocHGlobal((int)nIdLen);
nRet = PackageIdFromFullName(pFirstPackage, nFlags, ref nIdLen, pIdBuffer);
var temp = Marshal.PtrToStructure(pIdBuffer, typeof(PACKAGE_ID));
packageId = (PACKAGE_ID)temp;
}
}
return packageId;
}
static void Main(string[] args)
{
string packageFamilyName = "Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe";
PACKAGE_ID packageId = getUWPVersion(packageFamilyName);
}
}
}
C++代码:
#include <Windows.h>
#include <appmodel.h>
#include <iostream>
#include <malloc.h>
#include <stdio.h>
struct Version {
USHORT Revision;
USHORT Build;
USHORT Minor;
USHORT Major;
};
Version getVantageVersion(PCWSTR packageFamilyName)
{
Version version{};
UINT32 packageCount = 0;
UINT32 bufferLength = 0;
UINT32 packageFilters = PACKAGE_FILTER_HEAD | PACKAGE_INFORMATION_BASIC;
GetPackagesByPackageFamily(packageFamilyName, &packageCount, NULL, &bufferLength, NULL);
//FindPackagesByPackageFamily(packageFamilyName, packageFilters, &packageCount, NULL, &bufferLength, NULL, NULL);//or
if (packageCount > 0)
{
PWSTR *packageFullNames = new PWSTR[packageCount];
if (!packageFullNames)return version;
WCHAR *buffer = new WCHAR[bufferLength];
if (!buffer)
{
delete[](packageFullNames);
return version;
}
GetPackagesByPackageFamily(packageFamilyName, &packageCount, packageFullNames, &bufferLength, buffer);
//FindPackagesByPackageFamily(packageFamilyName, packageFilters, &packageCount, packageFullNames, &bufferLength, buffer, NULL);//or
UINT32 nFlags = PACKAGE_INFORMATION_BASIC;
PWSTR pFirstPackage = packageFullNames[0];
UINT32 nIdLen = 0;
LONG nRet = PackageIdFromFullName(pFirstPackage, nFlags, &nIdLen, NULL);
if (nIdLen > 0 && nRet == ERROR_INSUFFICIENT_BUFFER)
{
BYTE * pIdBuffer = new BYTE[nIdLen];
if (NULL != pIdBuffer)
{
nRet = PackageIdFromFullName(pFirstPackage, nFlags, &nIdLen, pIdBuffer);
if (nRet == ERROR_SUCCESS)
{
PACKAGE_ID *pID = (PACKAGE_ID*)pIdBuffer;
version.Build = pID->version.Build;
version.Major = pID->version.Major;
version.Minor = pID->version.Minor;
version.Revision = pID->version.Revision;
}
delete[](pIdBuffer);
}
}
delete[](packageFullNames);
delete[](buffer);
}
return version;
}
int main()
{
Version v = getVantageVersion(L"Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe");
}