Get UWP Version(不使用额外的nuget包或SDK)

这篇博客介绍了如何在不依赖额外nuget包或SDK的情况下,通过C#和C++代码获取Windows UWP应用的版本信息。首先,使用PowerShell获取所有UWP应用的详细信息,然后通过C#或C++的DllImport调用来解析PackageFamilyName,获取到版本号等关键数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值