使用套件識別碼除錯

許多Windows API(推播通知、背景任務、分享目標、啟動任務、Windows AI API)都要求你的應用程式擁有package 身份碼。 在開發過程中,你不想每次測試都建立完整的 MSIX 安裝程式——Winapp 提供兩個指令,可以即時賦予你的應用程式身份。

使用 Visual Studio 進行打包專案? 如果你已經在用 Visual Studio 來做套件專案,那你很可能不需要 Winapp 來除錯。 Visual Studio 已經能處理套件註冊、身份驗證、AUMID 啟用、除錯器附加及啟用碼除錯——這些都是在 F5 上完成的。 它也提供 除錯→其他除錯目標→除錯安裝應用程式套件 ,適用於進階情境。 以下工作流程對 VS Code 使用者、終端機型工作流程,以及 VS 原生未打包的框架 (如 Rust、Flutter、Tauri、Electron、純 C++)最有用。

兩種方法: winapp run vs create-debug-identity

winapp run create-debug-identity
它所記錄的內容 完整的鬆散版面套件(整個資料夾) Sparse 套件(單一執行檔)
應用程式啟動方式 由 winapp 啟動(AUMID 啟動或執行別名) 你自己啟動執行檔(命令列、IDE 等)。
模擬 MSIX 安裝 是的——最接近生產行為 不,僅限於稀疏身份識別
檔案會保留在原位 複製到 AppX 佈局目錄 是的——exe 會維持原本的路徑
身份識別範圍 整個資料夾內容(exe、DLL、資產) 單一執行檔
對除錯器友善 啟動後再連接 PID,或用 --no-launch 別名啟動 直接從你的 IDE 除錯器開啟——無論如何,執行檔都有其身份
主機應用程式支援 --with-alias 讓STDIN/STDOUT都維持在終端狀態 直接在終端機執行 exe
適用對象 大多數框架(.NET、C++、Rust、Flutter、Tauri) Electron,或是當你需要完整的 IDE 除錯器控制(F5)

何時使用哪一種

預設:winapp run

適用於 winapp run 大多數開發工作流程。 它模擬了真實的 MSIX 安裝——你的應用程式獲得與生產環境相同的身份、功能與檔案關聯。

# Build your app, then:
winapp run .\build\output

create-debug-identity 的使用時機:

  • 你的執行檔和建置輸出是分開的——例如,Electron 應用程式的 electron.exe 位於 node_modules/
  • 你需要除錯啟動程式碼 ,AUMID 推出後無法快速附加除錯器
  • 有些除錯器無法使用 AUMID 啟動,且在啟動的程序上需要具有身分標識。create-debug-identity會註冊該 exe,使其無論如何啟動都有身分標識。
  • 你是在測試稀疏套件的行為 (AllowExternalContent、TrustedLaunch)。
# Register identity for an exe, then launch it however you want:
winapp create-debug-identity .\bin\Debug\myapp.exe
.\bin\Debug\myapp.exe   # or F5 in your IDE

除錯情境

情境A:直接使用身份來執行

最簡單的工作流程是建立、執行、進行身份驗證,完成。

winapp run .\build\Debug

Winapp 會將資料夾註冊為一個鬆散的版面套件,然後啟動應用程式。 需要身份的 API 立即生效。 這涵蓋了大多數的開發與測試情境。

對於目前終端機需要 stdin/stdout 的 主控台應用程式 ,請新增 --with-alias

winapp run .\build\Debug --with-alias

情境 B:將除錯器附加到執行中的應用程式

啟動 winapp run,記錄 PID,然後附加你的 IDE 除錯器。

winapp run .\build\Debug
# Output: Process ID: 12345

然後在您的 IDE 中:

  • VS Code:執行並除錯→選擇「附加」設定(詳見下方 IDE 設定
  • WinDbgwindbg -p 12345

限制: 你會錯過任何在接駁前執行的程式碼。 啟動除錯時,請使用情境 D(create-debug-identity)。

情境 C:註冊身份,然後透過 AUMID 或別名從你的 IDE 啟動

--no-launch 來註冊套件,然後透過 AUMID(由 run 報告)或從 IDE 使用 執行別名 啟動應用程式。

步驟一: 註冊套件而無需啟動:

winapp run .\build\Debug --no-launch

步驟二: 設定你的 IDE 透過 AUMID 或 執行別名 啟動(不要直接用執行檔)。

  • 使用 AUMID 發射:使用指令 start shell:AppsFolder\<AUMID>winapp run 當應用程式註冊時,會輸出 AUMID。
  • 使用別名啟動:別名必須在你的清單中定義(Package.appxmanifest 偏好且 appxmanifest.xml 支援)。

重要: 單純在建置資料夾啟動 exe 並不會 給出它的身份。 應用程式必須透過 AUMID 啟動或使用其執行別名來啟動。 這就是鬆散版面套件的運作方式——身份是綁定在啟用路徑上,而不是 exe 檔。

情境 D:從你的 IDE 以身份啟動(啟動除錯)

這是 用完整 IDE 控制來除錯啟動程式碼 的最佳方法——你的 IDE 除錯器從第一條指令開始控制整個流程,且 exe 無論如何啟動都有身份。

winapp create-debug-identity .\build\Debug\myapp.exe

現在你可以用任何方式啟動這個 exe——從終端機、從 VS Code 的 F5 鍵,或是從腳本啟動。 這個 exe 擁有唯一標識,因為 Windows 註冊了一個直接指向它的 sparse package

它與winapp run的差異在於: 使用create-debug-identity,身份與 exe 本身繫結(透過Add-AppxPackage -ExternalLocation)。 在 winapp run 中,身份與松散佈局包綁定——應用程式必須透過 AUMID 或別名啟動。 當你需要 IDE 直接啟動並調試 .exe 檔案時,create-debug-identity 是更好的選擇。

這也是當 Electron 應用程式 的 exe 路徑與來源目錄不一致時的最佳方法。

情境 E:擷取除錯輸出與當機診斷

OutputDebugString 嵌捕捉訊息與首次例外。 框架雜訊(WinUI、COM、DirectX 內部追蹤)會從主控台過濾,所以只會顯示應用程式的除錯訊息。 所有資料仍會寫入日誌檔案以供全面調查。

若應用程式當機,會自動擷取並分析一個迷你轉印:

winapp run .\build\Debug --debug-output

當機時,輸出會包含例外類型、訊息和堆疊追蹤,並附上原始檔案和行號(從你建置輸出資料夾中的 PDB 解析出來)。 管理型(.NET)當機可即時分析,無需外部工具。 原生(C++/WinRT)崩潰時會顯示模組名稱與偏移量,加入 --symbols 以下載具有完整函式名稱的 PDB 符號。

winapp run .\build\Debug --debug-output --symbols

重要: 這會附加 Winapp 作為除錯器。 Windows每個進程只允許一個除錯器,所以你不能還要附加 Visual Studio、VS Code 或 WinDbg。

IDE 設定

VS Code

WinApp VS Code 擴充功能提供自訂winapp除錯類型,能以套件身份啟動應用程式並附加除錯器——只需按下一次 F5 即可完成。

單鍵 F5 除錯與身份驗證

請將啟動設定 winapp 新增至 .vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "winapp",
            "request": "launch",
            "name": "WinApp: Launch and Attach"
        }
    ]
}

按下 F5 時:

  1. 這個擴充功能會掃描你的工作區,尋找包含 .exe 檔案的建置輸出目錄。
  2. 你選擇要執行的建構資料夾(或設定 inputFolder 跳過提示)。
  3. 它透過winapp run啟動應用程式,賦予它套件識別。
  4. 子除錯會話會使用你指定的除錯器附加到正在執行的進程上。

一旦調試器附加,你就能體驗完整的 VS Code 除錯功能 —— 點擊面板設定斷點,逐行執行程式碼 F10,進入函式 F11,在 變數 面板檢查變數,並在 除錯主控台評估表達式。 應用程式以套件身份全程執行,因此依賴身份的 API 行為會如同在生產環境中完全一致。

重要:winapp除錯類型不會自動建置你的專案。 修改程式碼後,在按 F5 前重建。

自動化建置 preLaunchTask

為了避免忘記重建,可以在每次進行除錯前新增一個包含 preLaunchTask 的設定,以自動建置你的專案:

  1. 定義一個建置任務 .vscode/tasks.json(.NET範例):
    {
        "version": "2.0.0",
        "tasks": [
            {
                "label": "build",
                "command": "dotnet",
                "type": "process",
                "args": ["build", "${workspaceFolder}"],
                "problemMatcher": "$msCompile"
            }
        ]
    }
    
  2. 請參考你的 launch.json
    {
        "type": "winapp",
        "request": "launch",
        "name": "WinApp: Launch and Attach",
        "preLaunchTask": "build"
    }
    

設定屬性

房產 類型 預設 Description
inputFolder 字串 通往包含你應用程式二進位檔的建置輸出資料夾的路徑(例如 ${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621)。 若未設定,系統會提示您選擇資料夾。
manifest 字串 AppX 清單檔案的路徑(例如 AppxManifest.xml、 、 Package.appxmanifestappxmanifest.xml)。 若未設定,CLI 會自動偵測輸入資料夾或當前目錄。
debuggerType 字串 coreclr 底層偵錯工具使用(coreclrcppvsdbgnode)。
workingDirectory 字串 工作區資料夾 應用程式的工作目錄。
args 字串 傳遞給應用程式的命令列參數。
outputAppxDirectory 字串 Loose Layout 套件的此輸出目錄。 預設是輸入資料夾裡的一個 AppX 資料夾。
port 數字 9229 node 僅限)用於 Node.js --inspect 監聽器和附件連接的端口。 當預設埠已被使用時,執行覆蓋操作。

支援的除錯器

debuggerType 語言 必要延期
coreclr (預設值) C# / .NET C# 開發套件
cppvsdbg C / C++ C/C++
node Node.js / 電子 內建

C++ 專案範例:

{
    "type": "winapp",
    "request": "launch",
    "name": "WinApp: Launch C++ App",
    "debuggerType": "cppvsdbg"
}

使用 Create Debug Identity 進行啟動除錯

如果你需要從第一條指令除錯啟動程式碼,F5 附著方法可能會漏掉早期程式碼。 相反地,請使用 Command Palette () 中的 Ctrl+Shift+P 指令,註冊一個稀疏套件給可執行檔,然後用標準除錯器啟動:

{
    "name": "Launch (with identity)",
    "type": "coreclr",
    "request": "launch",
    "program": "${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621/myapp.exe"
}

由於 create-debug-identity 身分識別會直接在執行檔中註冊,因此無論以何種方式啟動,應用程式都具備身分識別——包括從標準的 Visual Studio Code 啟動設定。

附加到正在執行的程序

如果你偏好從終端機啟動 winapp run 再接駁,請使用標準的連接配置:

{
    "name": "Attach to Process",
    "type": "coreclr",
    "request": "attach",
    "processId": "${command:pickProcess}"
}

對於 C++/Rust,請使用 "type": "cppvsdbg" (MSVC) 或 "type": "lldb" (LLDB):

{
    "name": "Attach (C++)",
    "type": "cppvsdbg",
    "request": "attach",
    "processId": "${command:pickProcess}"
}

清理

測試結束後,從指令面板執行 WinApp: Unregister Package 移除側載開發套件,且不離開 VS Code。