Paket Kimliği ile Hata Ayıklama

Birçok Windows API'si (anında iletme bildirimleri, arka plan görevleri, hedefi paylaşma, başlangıç görevleri Windows yapay zeka API'leri) uygulamanızın package identity sahip olmasını gerektirir. Geliştirme sırasında, her testinizde tam bir MSIX yükleyicisi oluşturmak istemezsiniz; winapp, uygulama kimliğinizi anında vermek için iki komut sağlar.

Paketleme projesiyle Visual Studio mi kullanıyorsunuz? Paketlenmiş projeniz için zaten Visual Studio kullanıyorsanız hata ayıklama için winapp'e ihtiyacınız yoktur. Visual Studio zaten paket kaydını, kimliği, AUMID etkinleştirmesini, hata ayıklayıcı eklemesini ve etkinleştirme kodu hata ayıklamasını F5 ile işler. Ayrıca gelişmiş senaryolar için Hata Ayıklama → Diğer Hata Ayıklama Hedefleri → Yüklü Uygulama Paketinde Hata Ayıklama sunar. Aşağıdaki iş akışları VS Code kullanıcıları, terminal tabanlı iş akışları ve VS'nin yerel olarak paketlemediği çerçeveler (Rust, Flutter, Tauri, Electron, plain C++) için en kullanışlıdır.

İki yaklaşım: winapp run vs create-debug-identity

winapp run create-debug-identity
Ne kaydeder Tam gevşek düzen paketi (klasörün tamamı) Hafif paket (tekli exe)
Uygulama nasıl başlatılır? winapp tarafından başlatıldı (AUMID'nin etkinleştirilmesi veya yürütme takma adı) Exe'yi kendiniz başlatırsınız (komut satırı, IDE vb.)
MSIX yüklemesini simüle eder Evet — üretim davranışına en yakın Hayır — yalnızca seyrek kimlik
Dosyalar yerinde kalır AppX düzen dizinine kopyalandı Evet — exe özgün yolunda kalıyor
Kimlik kapsamı Tüm klasör içeriği (exe, DLL'ler, varlıklar) Tek yürütülebilir dosya
Hata ayıklayıcı dostu Başlatıldıktan sonra PID'ye bağlanma veya alias kullanarak başlatma --no-launch Doğrudan IDE'nizin hata ayıklayıcısından başlatın; exe her durumda kimliğini korur.
Konsol uygulaması desteği --with-alias stdin/stdout'un terminalde kalmasını sağlar Exe'yi doğrudan terminalde çalıştırma
En uygun Çoğu çerçeve (.NET, C++, Rust, Flutter, Tauri) Elektron veya tam IDE hata ayıklayıcısı denetimine ihtiyacınız olduğunda (F5)

Ne zaman kullanılır?

Varsayılan: winapp run

Çoğu geliştirme iş akışı için kullanın winapp run . Gerçek bir MSIX yüklemesinin benzetimini yapar; uygulamanız üretimde sahip olduğu kimlik, yetenek ve dosya ilişkilendirmeleriyle aynı olur.

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

Şu durumlarda kullanın create-debug-identity :

  • Exe'niz derleme çıkışınızdan ayrıdır — örneğin, electron.exe içinde yaşayan node_modules/ Electron uygulamaları
  • Başlangıç kodunda hata ayıklamanız gerekiyor ve AUMID başlatıldıktan sonra yeterince hızlı bir hata ayıklayıcı ekleyemezsiniz
  • AUMID ile başlatılamayan ve başlatılan süreçte kimliğe ihtiyaç duyulan bazı hata ayıklayıcılar ile, create-debug-identity exe dosyasını kaydeder, böylece her başlatıldığında kimliğe sahip olur
  • Seyrek paket davranışını özel olarak test ediyorsun (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

Hata ayıklama senaryoları

Senaryo A: Sadece kimlikle çalıştır

En basit iş akışı: derleme, kimlikle çalıştırma, bitti.

winapp run .\build\Debug

Winapp klasörü gevşek bir düzen paketi olarak kaydeder ve uygulamayı başlatır. Kimlik gerektiren API'ler hemen çalışır. Bu, geliştirme ve test senaryolarının çoğunu kapsar.

Geçerli terminalde stdin/stdout gerektiren konsol uygulamaları için ekleyin --with-alias:

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

Senaryo B: Çalışan bir uygulamaya hata ayıklayıcı ekleme

ile winapp runbaşlatın, PID'yi not edin ve ardından IDE'nizin hata ayıklayıcısını ekleyin.

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

Ardından IDE'nizde:

  • VS Code: Çalıştırma ve Hata Ayıklama → "Ekle" yapılandırmasını seçin (aşağıdaki IDE kurulumuna bakın)
  • WinDbg: windbg -p 12345

Sınırlama: Bağlamadan önce çalıştırılan tüm kodları kaçıracaksınız. Başlangıç hata ayıklaması için Senaryo D (create-debug-identity) kullanın.

Senaryo C: Kimliği kaydedin, ardından IDE'nizden AUMID veya diğer ad aracılığıyla başlatın

Paketi kaydetmek için --no-launch kullanarak, ardından uygulamayı run tarafından bildirilen AUMID veya IDE'nizden yürütme takma adı aracılığıyla başlatın.

1. Adım: Paketi başlatmadan kaydedin:

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

2. Adım: IDE'nizi AUMID veya yürütme diğer adı (doğrudan exe değil) aracılığıyla başlatacak şekilde yapılandırın.

  • AUMID ile başlatma: komutunu start shell:AppsFolder\<AUMID>kullanın. winapp run uygulama kaydedildiğinde AUMID'yi çıkış olarak verir.
  • Diğer adla başlatma: Diğer ad bildiriminizde tanımlanmalıdır (Package.appxmanifest tercih edilir, appxmanifest.xml ayrıca desteklenir).

Önemli: Exe dosyasını derleme klasöründe başlatmak, bu klasöre kimlik vermez. Uygulamanın AUMID etkinleştirmesi veya çalıştırma takma adı aracılığıyla başlatılması gerekir. Gevşek düzen paketleri bu şekilde çalışır. Kimlik, exe dosyasına değil etkinleştirme yoluna bağlıdır.

Senaryo D: Kimlik bilgileriyle IDE'den başlatma (başlatma sırasında hata ayıklama)

Bu, tam IDE denetimiyle başlangıç kodunda hata ayıklamak için en iyi yaklaşımdır. IDE'nizin hata ayıklayıcısı başlangıçtan itibaren işlemi denetler ve exe, nasıl başlatılırsa başlatılsın kimliğini korur.

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

Şimdi exe dosyasını istediğiniz gibi başlatın; terminalden, VS Code'un F5'inden, bir betikten. EXE dosyası, Windows'un doğrudan ona işaret eden bir sparse paketi kaydetmiş olması nedeniyle kimlik bilgisine sahiptir.

winapp run ile nasıl farklıdır:create-debug-identity ile, kimlik exe'nin kendisine bağlıdır (c3 /> aracılığıyla). winapp run ile kimlik, serbest düzen paketine bağlıdır; uygulama AUMID veya bir takma ad aracılığıyla başlatılmalıdır. Bu, IDE'nizin exe'yi doğrudan başlatıp hatalarını ayıklamasına ihtiyacınız olduğunda create-debug-identity daha iyi bir seçim yapar.

Bu ayrıca, exe yolunun kaynak dizininizden farklı olduğu Electron uygulamaları için de en iyi yaklaşımdır.

Senaryo E: Hata ayıklama çıkışını ve çökme teşhislerini yakalama

İletileri ve ilk şans özel durumlarını satır içinde yakalayın OutputDebugString . Çerçeve gürültüsü (WinUI, COM, DirectX iç izlemeleri) konsolundan filtrelenir, böylece yalnızca uygulamanızın hata ayıklama iletileri görüntülenir. Her şey hala tam araştırma için log dosyasına yazılmaktadır.

Uygulama kilitlenirse, bir minidump otomatik olarak yakalanır ve analiz edilir.

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

Çökme sırasında, kaynak dosya ve satır numaralarıyla (derleme çıktı klasörünüzdeki PDB'lerden çözümlenen) hata türünü, iletiyi ve hata izlemesini içeren bir çıktı üretilir. Yönetilen (.NET) kilitlenmeler harici araçlar olmadan anında analiz edilir. Yerel (C++/WinRT) kilitlenmeleri modül adlarını ve offset'lerini gösterir; tam işlev adları için PDB sembollerini indirmek amacıyla --symbols ekleyin.

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

Önemli: Bu işlem winapp'i hata ayıklayıcısı olarak ekler. Windows işlem başına yalnızca bir hata ayıklayıcıya izin verir, bu nedenle Visual Studio, VS Code veya WinDbg bağlayamazsınız.

WinUI saklanan özel durum ayıklaması

Çoğu WinUI kilitlenmesi bir XAML olay işleyicisinin içinde başlar ve daha sonra dispatcher tarafından yeniden fırlatılan bir stowed exception (0xC000027B) olarak ortaya çıkar; bu nedenle normal çağrı yığını artık gerçek nedene işaret etmez. Çöken uygulama yüklendiğinde Microsoft.UI.Xaml.dll, winapp, stowed exception'ı ve yerel XAML gönderim zincirini (Microsoft.UI.XamlCXcpDispatcherCoreMessagingXP → CLR host) çözümlayan ek bir tanılama geçişini otomatik olarak çalıştırır. Sonuç, hata ayıklama günlüğüne eklenir. İşaret gerekmez — WinUI dökümleri için otomatik olarak etkinleştirilir. Çağrı zincirindeki tamamen çözümlenmiş işlev adları için --symbols ekleyin.

Bunun çalışması için winapp, ilk-fırsat iş parçacığı bağlamını korurken, sonlandıran saklı özel durumun kaydıyla (ve saklı özel durum dizisini işaret eden parametreleriyle birlikte) kilitlenme dökümünü yakalar; böylece standart yönetilen analiz özgün kullanıcı çerçevenizi yine kurtarabilir ve triyaj geçişi saklı özel durumu bulabilir.

Bu geçiş, WinUI ekibinin WinDbg JavaScript uzantısıyla DbgEng'i barındırıyor. Yerel hata ayıklama motoru (dbgeng.dll ve benzerleri) NuGet'ten gelir ve NuGet'te bulunmayan JavaScript betik barındırıcısı olan JsProvider.dll, ilk kullanımda doğrudan resmî WinDbg indirmesinden alınır (paketin tamamı değil, yalnızca gereken birkaç yüz kilobayt okunur). JsProvider.dll motorla aynı derleme olması gerektiği için — uyumsuz bir sağlayıcının yüklenmesi, hata ayıklayıcının başlangıçta çökmesine neden olur — NuGet motoruyla derlemesi eşleşen belirli WinDbg paketine sabitlenmiştir (sürekli güncellenen "current" sürümüne değil) ve edinildikten sonra iki derleme karşılaştırılır: uyuşmazlık varsa reddedilir ve sessizce çökmek yerine açık bir gerekçeyle triyaj atlanır. Hata ayıklayıcı paketlerinin sürümleri sabitlenmiştir ve bunların yerel DLL'lerinden herhangi biri çıkarılıp yüklenmeden önce, derlemeye gömülü bir SHA-512 içerik karmasına göre (uzantı da ayrıca sabitlenmiş bir karmaya göre) doğrulanır; JsProvider.dll için ayrıca, sertifika zincirinin iptal durumu tam olarak denetlenerek kontrol edilen geçerli bir Microsoft Authenticode imzası bulunması zorunludur (iptal verilerine çevrimdışı durumda erişilemediğinde yalnızca imza denetimine geri dönülür, ancak iptal edilmiş bir sertifika her durumda reddedilir). İndirmeler geçici bir dosyaya hazırlanır, doğrulanır, ardından önbelleğe atomik olarak yayımlanır, dolayısıyla eş zamanlı çalıştırma hiçbir zaman kısmen yazılmış veya doğrulanmamış bir DLL'yi gözlemlemez. Her çalıştırmada önbelleğe alınmış ikili dosyalar yeniden denetlenir (JsProvider.dll imzası ile bunun altyapı derlemesinin eşleşip eşleşmediği ve altyapı DLL'lerinin geçerli bir PE görüntüsü olup olmadığı kontrol edilir); bu sayede kesilmiş veya bozulmuş bir önbellek, her çalıştırmada başarısız olmak yerine bileşenleri yeniden edinerek kendini onarır. Bu, yansıtılmış veya güvenliği aşılmış bir akışın değiştirilmiş ikili dosyaları değiştiremeyeceği anlamına gelir; herhangi bir hata, doğrulamasız kodu yüklemek yerine önceliklendirmeyi atlar. Her şey winapp genel dizini altında önbelleğe alınır, bu nedenle sonraki çalıştırmalar çevrimdışı olur. Ortamınız bu indirmeleri engelliyorsa, Windows için Hata Ayıklama Araçları'nı yükleyin (Windows SDK aracılığıyla) veya ortam değişkenini zaten ve WINAPP_DBGTOOLS_DIRiçeren dbgeng.dll bir hata ayıklayıcı dizinine ayarlayınJsProvider.dll. WINAPP_DBGTOOLS_DIR ayarlandığında esas alınır — yalnızca bu dizin dikkate alınır — bu nedenle eksikse, günlükte zaten ayarlanmış olan bir değişkeni ayarlamanız önerilmek yerine belirli eksik bileşen (dbgeng.dll ve/veya JsProvider.dll) belirtilir. Triyaj başarılı olduğunda konsol tek satırlık bir sonuç gösterir (istiflenmiş özel durumun hata kodu/iletisi); ikili dosyalar elde edilemediğinde triyaj geçişi atlanır (standart yönetilen/yerel analiz hâlâ çalışır), konsol bunu belirtir ve günlük nedenini açıklar.

Triyaj geçişi kısa ömürlü bir alt işlemde çalışır. Bu şu nedenle gereklidir: winapp'in ana süreci, dökümü yakalayıp analiz ederken sistem dbghelp.dll’ını yükler ve modern motor dbgeng.dll, bellekte zaten yer alan bu eski kopyaya bağlanamaz; yeni bir süreç motora temiz bir yükleyici durumu sağlar. Stowed exception yapılarının çözümlenmesi için işletim sistemi sembolleri de gerekir; bunları --symbols, Microsoft genel sembol sunucusundan indirir (combase.dll). Sembollerinin burada yayımlanmadığı derlemelerde triyaj geçişi yine de stowed exception’ı saptar, ancak onu tam olarak ayrıntılandıramaz.

IDE kurulumu

VS Code

WinApp VS Code uzantısı, uygulamanızı paket kimliğiyle başlatan ve tek bir winapp basımından hata ayıklayıcısını ekleyen özel bir hata ayıklama türü sağlar. Visual Studio Market'ten yükleyin; kaynağı ve sorun izleyicisi microsoft/WinAppVSCE deposunda canlı olarak bulunur.

Kimlik doğrulamayı kullanarak tek tuşla F5 hata ayıklaması

winapp başlatma yapılandırmasını .vscode/launch.json içerisine ekleyin:

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

F5 tuşuna bastığınızda:

  1. Uzantı, .exe dosyalarını içeren derleme çıktısı dizinleri için çalışma alanınızı tarar.
  2. Çalıştırmak için derleme klasörünü seçersiniz (veya istemi atlamak için inputFolder ayarlarsınız).
  3. winapp run aracılığıyla uygulamanıza paket kimliği vermek için başlatır.
  4. Çocuk hata ayıklama oturumu, belirttiğiniz hata ayıklayıcıyı kullanarak çalışan işleme eklenir.

Hata ayıklayıcı eklendikten sonra tam VS Code hata ayıklama deneyimini elde edersiniz. Bölme çubuğuna tıklayarak kesme noktaları ayarlayın, kodda satır satır ilerleyin (F10 ), işlevlere adımlayın (F11 ), Değişkenler bölmesinde değişkenleri inceleyin ve Hata Ayıklama Konsolu'ndaki ifadeleri değerlendirin. Uygulama boyunca paket kimliğiyle çalıştığından, kimliğe bağımlı API'ler üretimde olduğu gibi davranır.

Önemli: Hata winapp ayıklama türü projenizi otomatik olarak oluşturmaz . Kod değişiklikleri yaptıktan sonra F5 tuşuna basmadan önce yeniden oluşturun.

Derlemeleri preLaunchTask ile otomatikleştirin

Yeniden derlemeyi unutmamak için, her hata ayıklama oturumundan önce projenizi oluşturan bir preLaunchTask ekleyin:

  1. .vscode/tasks.json içinde bir derleme görevi tanımlama (.NET örneği):
    {
        "version": "2.0.0",
        "tasks": [
            {
                "label": "build",
                "command": "dotnet",
                "type": "process",
                "args": ["build", "${workspaceFolder}"],
                "problemMatcher": "$msCompile"
            }
        ]
    }
    
  2. Bunu launch.json içinde belirtin.
    {
        "type": "winapp",
        "request": "launch",
        "name": "WinApp: Launch and Attach",
        "preLaunchTask": "build"
    }
    

Yapılandırma özellikleri

Mülkiyet Türü Varsayılan Description
inputFolder string Uygulama ikili dosyalarınızı içeren derleme çıkış klasörünün yolu (ör. ${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621). Ayarlanmamışsa, bir klasör seçmeniz istenir.
manifest string AppX bildirim dosyasının yolu (ör. , AppxManifest.xmlPackage.appxmanifestveya appxmanifest.xml). Ayarlanmazsa, CLI giriş klasöründen veya geçerli dizinden otomatik olarak algılar.
debuggerType string coreclr (coreclr, cppvsdbgveya node) kullanılacak temel hata ayıklayıcı
workingDirectory string çalışma alanı klasörü Uygulama için çalışma dizini.
args string Uygulamaya geçirmek için komut satırı bağımsız değişkenleri.
outputAppxDirectory string Gevşek düzen paketi için çıkış dizini. Giriş klasörünün içindeki bir AppX klasörü varsayılan olarak kullanır.
port number 9229 (node yalnızca) Node.js --inspect dinleyicisi ve bağlama bağlantısı için kullanılan port. Varsayılan bağlantı noktası zaten kullanımda olduğunda geçersiz kılın.

Desteklenen hata ayıklayıcıları

debuggerType Language Gerekli Uzantı
coreclr (varsayılan) C# / .NET C# Geliştirme Seti
cppvsdbg C / C++ C/C++
node Node.js / Elektron Dahili

C++ projesi örneği:

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

Hata Ayıklama Kimliği Oluştur ile hata ayıklamayı başlatma

Başlangıç kodunda ilk yönergeden itibaren hata ayıklamanız gerekiyorsa, F5 ile ekleme yöntemi erken kodu kaçırabilir. Bunun yerine, yürütülebilir dosyanız için seyrek bir paket kaydetmek için Komut Paleti'nden () Ctrl+Shift+P komutunu kullanın ve ardından standart hata ayıklayıcınızla başlatın:

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

Kimlik, exe'ye doğrudan kaydedildiğinden, standart VS Code başlatma yapılandırması da dahil olmak üzere, uygulama nasıl başlatılırsa başlatılsın kimliğe sahiptir.

Çalışan işleme ekleme

ile terminalden başlatmayı winapp run ve ardından eklemeyi tercih ediyorsanız standart bir ekleme yapılandırması kullanın:

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

C++/Rust için (MSVC) veya "type": "cppvsdbg" (LLDB) kullanın "type": "lldb" :

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

Temizleme

Testi tamamladığınızda, VS Code'dan çıkmadan dışarıdan yüklenen geliştirme paketlerini kaldırmak için Komut Paletinden WinApp: Paketin Kaydını Sil'i çalıştırın.