[英]How do I find the target of a Windows App Execution Alias in C#/Win32 api?
Microsft Windows 終端(通過 Microsoft Store 安裝)創建一個 0 字節的wt.exe
文件,該文件是Windows 執行別名。 AFAIK 它類似於符號鏈接,除了它似乎在CreateProcess
Api 級別解決,而不是在文件系統中翻譯的符號鏈接。
在 powershell 中:
❯ dir ~\AppData\Local\Microsoft\WindowsApps\wt.exe
Mode Name
---- ----
la--- wt.exe -> C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.0.1401.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
❯ Get-Item .\wt.exe | fl
Name : wt.exe
Length : 0
LinkType : AppExeCLink
Target : C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.0.1401.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
我無法為這些“新”類型的別名找到適當的文檔。 即使谷歌搜索 PS AppExeCLink
值也不是很有用。
我需要一種快速的方法來解決 C# 應用程序中的執行別名(獲取目標文件)。 鑒於我的要求,與添加對慢速 WMI 或外部 300kb nuget package 的引用相比,我更喜歡非托管 (Win32 Api) 方式。
謝謝!
我在我的系統工具庫中遇到了同樣的問題,它被這些新型鏈接阻塞了。 這個庫是用 C 編寫的,使用 WIN32 API。
這是我到目前為止發現的:
在 Windows、cmd.exe 和 PowerShell 5.1 中引入它們三年后,仍然不知道 App Exec 鏈接,並將它們報告為 0 字節文件。
但是 PowerShell Core 7 知道它們:
PS C:\Temp> dir $env:LOCALAPPDATA\Microsoft\WindowsApps |?{$_.LinkType} | select Name,LinkType,Target Name LinkType Target ---- -------- ------ GameBarElevatedFT_Alias.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.XboxGamingOverlay_5.420.11102.0_x64__8w... MicrosoftEdge.exe AppExeCLink C:\WINDOWS\system32\SystemUWPLauncher.exe python.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w... python3.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w... ubuntu.exe AppExeCLink C:\Program Files\WindowsApps\CanonicalGroupLimited.UbuntuonWindows_2004.2020.8... ubuntu1804.exe AppExeCLink C:\Program Files\WindowsApps\CanonicalGroupLimited.Ubuntu18.04onWindows_2020.1... WinFR.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.WindowsFileRecovery_0.1.13492.0_x64__8w... winget.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.11.3162.0_x64__8w... wt.exe AppExeCLink C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3... PS C:\Temp>
這些 App Exec 鏈接是 NTFS 重解析點,標記為
IO_REPARSE_TAG_APPEXECLINK = 0x8000001b。
您可以使用帶有FSCTL_GET_REPARSE_POINT
控制代碼的 WIN32 API DeviceIoControl()
在 C/C++/C# 程序中讀取它們。
我的readlink.c模塊包含一個ReadReparsePointW()
例程來演示這一點。
您可以通過運行以下命令轉儲此類鏈接的內容:
fsutil reparsepoint query <REPARSE_POINT_PATHNAME>
前任:
C:\Temp>fsutil reparsepoint query "%LOCALAPPDATA%\Microsoft\WindowsApps\wt.exe" Reparse Tag Value: 0x8000001b Tag value: Microsoft Reparse Data Length: 0x168 Reparse Data: 0000: 03 00 00 00 4d 00 69 00 63 00 72 00 6f 00 73 00....Mic.r.os 0010: 6f 00 66 00 74 00 2e 00 57 00 69 00 6e 00 64 00 oft..Wind 0020: 6f 00 77 00 73 00 54 00 65 00 72 00 6d 00 69 00 owsTer.mi 0030: 6e 00 61 00 6c 00 5f 00 38 00 77 00 65 00 6b 00 nal_.8.wek 0040: 79 00 62 00 33 00 64 00 38 00 62 00 62 00 77 00 yb3.d.8.bbw 0050: 65 00 00 00 4d 00 69 00 63 00 72 00 6f 00 73 00 e...Mic.r.os 0060: 6f 00 66 00 74 00 2e 00 57 00 69 00 6e 00 64 00 oft..Wind 0070: 6f 00 77 00 73 00 54 00 65 00 72 00 6d 00 69 00 owsTer.mi 0080: 6e 00 61 00 6c 00 5f 00 38 00 77 00 65 00 6b 00 nal_.8.wek 0090: 79 00 62 00 33 00 64 00 38 00 62 00 62 00 77 00 yb3.d.8.bbw 00a0: 65 00 21 00 41 00 70 00 70 00 00 00 43 00 3a 00 e...App..C:.: 00b0. 5c 00 50 00 72 00 6f 00 67 00 72 00 61 00 6d 00 \.P.r.ogr.am: 00c0. 20 00 46 00 69 00 6c 00 65 00 73 00 5c 00 57 00.Files\.W: 00d0. 69 00 6e 00 64 00 6f 00 77 00 73 00 41 00 70 00 indowsAp: 00e0. 70 00 73 00 5c 00 4d 00 69 00 63 00 72 00 6f 00 ps\.Mic.r.o: 00f0. 73 00 6f 00 66 00 74 00 2e 00 57 00 69 00 6e 00 soft..Win: 0100. 64 00 6f 00 77 00 73 00 54 00 65 00 72 00 6d 00 dowsTer.m: 0110. 69 00 6e 00 61 00 6c 00 5f 00 31 00 2e 00 34 00 inal_.1...4: 0120. 2e 00 33 00 32 00 34 00 33 00 2e 00 30 00 5f 00..3.2.4.3...0._: 0130. 78 00 36 00 34 00 5f 00 5f 00 38 00 77 00 65 00 x.6.4._._.8.we: 0140. 6b 00 79 00 62 00 33 00 64 00 38 00 62 00 62 00 kyb3.d.8.bb: 0150. 77 00 65 00 5c 00 77 00 74 00 2e 00 65 00 78 00 we\.wt..ex: 0160. 65 00 00 00 30 00 00 00 e...0..: C:\Temp>
重新解析的數據有一個包含四個寬字符串的結構,如下所示:
typedef struct _REPARSE_APPEXECLINK_READ_BUFFER { // For tag IO_REPARSE_TAG_APPEXECLINK DWORD ReparseTag; WORD ReparseDataLength; WORD Reserved; ULONG Version; // Currently version 3 WCHAR StringList[1]; // Multistring (Consecutive UTF-16 strings each ending with a NUL) /* There are normally 4 strings here. Ex: Package ID: L"Microsoft.WindowsTerminal_8wekyb3d8bbwe" Entry Point: L"Microsoft.WindowsTerminal_8wekyb3d8bbwe:App" Executable: L"C.\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\wt.exe" Applic: Type. L"0" // Integer as ASCII; "0" = Desktop bridge application, Else sandboxed UWP application */ } APPEXECLINK_READ_BUFFER; *PAPPEXECLINK_READ_BUFFER;
運行 wt.exe 的 App Exec Link 目標...
"C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.4.3243.0_x64__8wekyb3d8bbwe\wt.exe"
... 工作,並啟動 Windows 終端。
但是運行 MicrosoftEdge.exe 的 App Exec Link 目標...
"C:\WINDOWS\system32\SystemUWPLauncher.exe"
... 什么也沒做。
⇒ 重解析數據中的其他參數在某種程度上很重要。 (但我不知道如何使用它們。)
跑步
"%LOCALAPPDATA%\Microsoft\WindowsApps\MicrosoftEdge.exe"
然后查看任務管理器,我看到為 MS Edge 運行的真正可執行文件是
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
⇒ 這證明了 App Exec Link 目標程序並不總是真正的程序。
可以使用重新解析數據中的入口點字符串而不是目標路徑名來啟動目標應用程序,使用:
explorer.exe shell:appsFolder\<REPARSE_POINT_ENTRY_POINT_NAME>
例如,這將啟動 Microsoft Edge:
explorer.exe shell:appsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge
但這不是我想要的。 我真的很想知道如何使用目標應用程序路徑名和其他兩個參數來啟動應用程序。
無論如何,我已經更新了我的MsvcLibX 庫中的 readlink() 例程以返回 App Exec Links 的目標。 我的系統工具庫中所有可以處理符號鏈接的工具現在都顯示了該目標。
但由於這個目標顯然不是完整的答案,我認為這個當前版本充其量只是一個臨時實現。
如果有人找到有關此主題的更多信息,我很感興趣!
您也可以嘗試將Microsoft.PowerShell.5.1.ReferenceAssemblies
nuget package 添加到您的項目中。
然后下面的代碼工作:
using System.Linq;
using System.Management.Automation;
string wtPath =
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"WindowsApps",
"wt.exe"
);
using (var ps = PowerShell.Create())
{
var psObject = ps.AddCommand("Get-Item").AddParameter("Path", wtPath).Invoke().Single();
var psPropInfo = psObject.Properties["Target"];
string[] targets = (psPropInfo.Value as List<string>).ToArray();
Console.WriteLine($"[{psPropInfo.Name}]=[{String.Join("; ", targets)}]");
}
以為我還會添加有關 UWP exe 和 WindowsApp 商店如何使用此 ReparsePoint 鏈接類型的相關線程。
tl;博士;
~\AppData\Local\Microsoft\WindowsApps\
目錄的 EXE 使用特殊形式的IO_REPARSE_TAG_APPEXECLINK
符號鏈接來引用位於C:/Program Files/WindowsApps/
中的實際 UWP pkg。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.