Get AppX/MSIX information by process

Post your working scripts, libraries and tools for AHK v1.1 and older
Ferry
Posts: 13
Joined: 10 Jul 2014, 15:55

Get AppX/MSIX information by process

Post by Ferry » 01 Feb 2023, 05:19

So i needed information on how i can get AppX/MSIX package information for existing running processes and the current process when the compiled AutoHotKey script is running within an AppX/MSIX container environment. I came up with the following functions you can use.

This script will start Notepad.exe and uses the PID to get the AppX Package information when it is started on a Windows 10 or Windows 11 operating system. If no PID information is used it will try to get this information for its own process.

https://learn.microsoft.com/en-us/windows/msix/msix-container
https://learn.microsoft.com/en-us/windows/win32/api/appmodel

Code: Select all

Run, Notepad.exe,, UseErrorLevel, PID

hProc := OpenProcess(PID)
PackageFullName := GetPackageFullName(hProc)
PackagePath := GetPackagePath(PackageFullName)
PackageFamilyName := GetPackageFamilyName(hProc)
If PackageFamilyName
	{
	StringSplit, PackageNamePublisherId, PackageFamilyName, _
	PackageName := PackageNamePublisherId1
	PublisherId := PackageNamePublisherId2
	}
Else
	{
	PublisherId =
	PackageName =
	}
AppUserModelId := GetApplicationUserModelId(hProc)
If AppUserModelId
	{
	StringSplit, AppUserModelIdAppiD, AppUserModelId, !
	AppID :=  AppUserModelIdAppiD2
	}
Else
	AppID =
MsgBox, PackagePath = %PackagePath%`nPackageFullName = %PackageFullName%`nPackageName = %PackageName%`nPublisherId = %PublisherId%`nPackageFamilyName = %PackageFamilyName%`nAppUserModelId = %AppUserModelId%`nAppId = %AppID%
ExitApp

; --------------------------------------------------------------- Functions for Collecting AppX/MSIX Package Information ---------------------------------------------------------------
OpenProcess(PID)
	{
	PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
	hProc := DllCall("OpenProcess", "UInt", PROCESS_QUERY_LIMITED_INFORMATION, "UInt", 0, "Ptr", PID, "Ptr")
	Return hProc	
	}
GetPackagePath(PackageFullName)
	{
	pathLength = 256
	bytes_per_char := A_IsUnicode ? 2 : 1
	GetCurrentPackagePathLength := pathLength * bytes_per_char
	VarSetCapacity(GetCurrentPackagePath, GetCurrentPackagePathLength)
	If PackageFullName
		DllCall("GetPackagePathByFullName", "Ptr", &PackageFullName, "Wstr", GetCurrentPackagePathLength, "Ptr", &GetCurrentPackagePath)
	Else
		DllCall("GetCurrentPackagePath", "Wstr", GetCurrentPackagePathLength, "Ptr", &GetCurrentPackagePath)
	PackagePath := StrGet(&GetCurrentPackagePath)
	Return PackagePath
	}
GetPackageFullName(hProc)
	{
	packageFullNameLength = 128
	bytes_per_char := A_IsUnicode ? 2 : 1
	GetCurrentPackageFullNameLength := packageFullNameLength * bytes_per_char
	VarSetCapacity(GetCurrentPackageFullName, GetCurrentPackageFullNameLength)
	If hProc
		DllCall("GetPackageFullName", "Uint", hProc, "Wstr", GetCurrentPackageFullNameLength, "Ptr", &GetCurrentPackageFullName)
	Else
		DllCall("GetCurrentPackageFullName", "Wstr", GetCurrentPackageFullNameLength, "Ptr", &GetCurrentPackageFullName)
	PackageFullName := StrGet(&GetCurrentPackageFullName)
	Return PackageFullName
	}
GetPackageFamilyName(hProc)
	{
	packageFamilyNameLength = 128
	bytes_per_char := A_IsUnicode ? 2 : 1
	GetCurrentPackageFamilyNameLength := packageFamilyNameLength * bytes_per_char
	VarSetCapacity(GetCurrentPackageFamilyName, GetCurrentPackageFamilyNameLength)
	If hProc
		DllCall("GetPackageFamilyName", "Uint", hProc, "Wstr", GetCurrentPackageFamilyNameLength, "Ptr", &GetCurrentPackageFamilyName)
	Else
		DllCall("GetCurrentPackageFamilyName", "Wstr", GetCurrentPackageFamilyNameLength, "Ptr", &GetCurrentPackageFamilyName)
	PackageFamilyName := StrGet(&GetCurrentPackageFamilyName)
	Return PackageFamilyName
	}
GetApplicationUserModelId(hProc)
	{
	applicationUserModelIdLength = 256
	bytes_per_char := A_IsUnicode ? 2 : 1
	GetCurrentApplicationUserModelIdLength := applicationUserModelIdLength * bytes_per_char		
	VarSetCapacity(GetCurrentApplicationUserModelId, GetCurrentApplicationUserModelIdLength)
	If hProc
		DllCall("GetApplicationUserModelId", "Uint", hProc, "Wstr", GetCurrentApplicationUserModelIdLength, "Ptr", &GetCurrentApplicationUserModelId)
	Else
		DllCall("GetCurrentApplicationUserModelId", "Wstr", GetCurrentApplicationUserModelIdLength, "Ptr", &GetCurrentApplicationUserModelId)
	AppUserModelId := StrGet(&GetCurrentApplicationUserModelId)
	Return AppUserModelId
	}

robodesign
Posts: 932
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: Get AppX/MSIX information by process

Post by robodesign » 05 Feb 2023, 03:53

Thank you for sharing this code.

Is it possible to determine from ahk if the product is bought or not?

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.

Ferry
Posts: 13
Joined: 10 Jul 2014, 15:55

Re: Get AppX/MSIX information by process

Post by Ferry » 10 Feb 2023, 05:51

Hi Marius,

I don't think you can determine if the product is bought but most App-X UWP applications are retrieved from the Microsoft Store. Some of them free and some of them paid. Using MSIX you now have the possibility to create your own UWP application for your own Win32 programs and scripts (AutoHotKey) so they can be deployed using the Microsoft Store. I'm currently working on my own Launcher created in AutoHotKey to provide support for other Legacy applications that are deliverd using an MSIX package for enterprise environments because there are some limitations that will not work with all applications for now.

Post Reply

Return to “Scripts and Functions (v1)”