Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Muchas API de Windows (notificaciones push, tareas en segundo plano, destino de recurso compartido, tareas de inicio Windows API de IA) requieren que la aplicación tenga package identity. Durante el desarrollo, no quieres compilar un instalador MSIX completo cada vez que lo pruebes — winapp proporciona dos comandos para proporcionar la identidad de la aplicación al vuelo.
¿Usar Visual Studio con un proyecto de empaquetado? Si ya está utilizando Visual Studio para tu proyecto empaquetado, quizás no necesites winapp para la depuración. Visual Studio ya gestiona el registro de paquetes, la identidad, la activación de AUMID, la vinculación del depurador y la depuración de código de activación, todo a través de F5. También ofrece depuración → otros destinos de depuración → Depurar paquete de aplicaciones instalado para escenarios avanzados. Los flujos de trabajo siguientes son más útiles para los usuarios de VS Code, los flujos de trabajo basados en terminales y los marcos que VS no empaqueta de forma nativa (Rust, Flutter, Tauri, Electron, plain C++).
Dos enfoques: winapp run frente a create-debug-identity
winapp run |
create-debug-identity |
|
|---|---|---|
| Lo que registra | Paquete de diseño flexible completo (carpeta completa) | Paquete disperso (exe único) |
| Cómo se inicia la aplicación | Iniciado por winapp (alias de activación o ejecución de AUMID) | Inicie el exe usted mismo (línea de comandos, IDE, etc.) |
| Simula la instalación de MSIX | Sí: más cercano al comportamiento de producción | No: solo identidad dispersa |
| Los archivos permanecen en su lugar | Copiado en un directorio de diseño de AppX | Sí — exe permanece en su camino original |
| Ámbito de identidad | Contenido completo de la carpeta (exe, DLL, assets) | Archivo ejecutable único |
| Depurador descriptivo | Adjúntese al PID después de iniciar, o utilice --no-launch y luego inicie a través de un alias. |
Iniciar directamente desde el depurador del IDE: el exe tiene identidad independientemente de cualquier otra variable. |
| Compatibilidad con aplicaciones de consola |
--with-alias mantiene stdin/stdout en el terminal |
Ejecutar exe directamente en el terminal |
| Mejor para | Mayoría de los marcos (.NET, C++, Rust, Flutter, Tauri) | Electron, o cuando necesita un control completo del depurador IDE (F5) |
Cuándo usar qué
Opción predeterminada: winapp run
Se usa winapp run para la mayoría de los flujos de trabajo de desarrollo. Simula una instalación de MSIX real: la aplicación obtiene la misma identidad, funcionalidades y asociaciones de archivos que tendría en producción.
# Build your app, then:
winapp run .\build\output
Utilice create-debug-identity si:
-
Tu exe es independiente de la salida de tu compilación, por ejemplo, las aplicaciones de Electron donde
electron.exese encuentranode_modules/ - Debe depurar el código de inicio y no puede conectar un depurador con suficiente rapidez después del inicio de AUMID.
-
Con algunos depuradores en los que no se puede iniciar con AUMID y se necesita que el proceso iniciado tenga identidad,
create-debug-identityregistra el exe para que tenga identidad sin importar cómo se inicie. - Está probando el comportamiento disperso del paquete específicamente (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
Escenarios de depuración
Escenario A: Simplemente ejecutar con identidad
El flujo de trabajo más sencillo: compilar, ejecutar con identidad, hecho.
winapp run .\build\Debug
Winapp registra la carpeta como un paquete de diseño flexible e inicia la aplicación. Las API que requieren identidad funcionan inmediatamente. Esto abarca la mayoría de los escenarios de desarrollo y pruebas.
Para las aplicaciones de consola que necesitan stdin/stdout en el terminal actual, agregue --with-alias:
winapp run .\build\Debug --with-alias
Escenario B: Adjuntar un depurador a una aplicación en ejecución
Inicie con winapp run, anote el PID y, a continuación, adjunte el depurador del IDE.
winapp run .\build\Debug
# Output: Process ID: 12345
A continuación, en tu IDE:
- VS Code: ejecutar y depurar → seleccionar la configuración "Adjuntar" (consulte la configuración del IDE a continuación)
-
WinDbg:
windbg -p 12345
Limitación: Se perderá cualquier código que se ejecute antes de adjuntarlo. Para la depuración del arranque, use el escenario D (
create-debug-identity).
Escenario C: Registrar identidad y, a continuación, iniciar a través de AUMID o alias desde el IDE
Use --no-launch para registrar el paquete y, a continuación, inicie la aplicación a través de su AUMID (notificado por run) o alias de ejecución desde el IDE.
Paso 1: Registre el paquete sin iniciar:
winapp run .\build\Debug --no-launch
Paso 2: Configure el IDE para que se inicie a través del AUMID o el alias de ejecución (no el exe directamente).
- Iniciar con AUMID: use el comando
start shell:AppsFolder\<AUMID>.winapp rungenera el AUMID cuando se registra la aplicación. - Iniciar con el alias: el alias debe definirse en el manifiesto (
Package.appxmanifestpreferido,appxmanifest.xmltambién compatible).
Importante: Simplemente iniciar el archivo exe en la carpeta de compilación no le dará identidad. La aplicación debe iniciarse a través de la activación de AUMID o su alias de ejecución. Este es el funcionamiento de los paquetes de diseño flexible: la identidad está vinculada a la ruta de activación, no al archivo exe.
Escenario D: Lanzamiento desde el IDE con configuración de identidad (depuración en el arranque)
Este es el mejor enfoque para depurar código de inicio con control IDE completo : el depurador del IDE controla el proceso desde la primera instrucción y el exe tiene identidad independientemente de cómo se inicie.
winapp create-debug-identity .\build\Debug\myapp.exe
Ahora inicie el archivo exe de la manera que quiera desde el terminal, desde el F5 de VS Code, desde un script. El exe tiene identidad porque Windows registró un paquete sparse apuntando directamente a él.
Cómo difiere de
winapp run: concreate-debug-identity, la identidad está vinculada al propio exe (a través deAdd-AppxPackage -ExternalLocation). Conwinapp run, la identidad está vinculada al paquete de diseño flexible; la aplicación debe iniciarse a través de AUMID o un alias. Esto hacecreate-debug-identityla mejor opción cuando necesita que el IDE inicie y depure el exe directamente.
Este es también el mejor enfoque para las aplicaciones Electron donde la ruta de acceso del ejecutable difiere del directorio de origen.
Escenario E: Captura de salida de depuración y diagnósticos de bloqueo
Capture OutputDebugString mensajes y excepciones de primera oportunidad en línea. El ruido del framework (WinUI, COM, seguimientos internos de DirectX) se filtra en la consola, por lo que solo aparecen los mensajes de depuración de tu aplicación. Todo continúa registrado en el fichero de registro para llevar a cabo una investigación exhaustiva.
Si la aplicación se bloquea, se captura y analiza automáticamente un minivolcado:
winapp run .\build\Debug --debug-output
En caso de falla, la salida incluye el tipo de excepción, el mensaje y el seguimiento de pila con el nombre del archivo fuente y números de línea (resueltos desde archivos PDB en la carpeta de salida de compilación). Los fallos administrados (.NET) se analizan de inmediato sin necesidad de herramientas externas. Los fallos nativos (C++/WinRT) muestran los nombres y desplazamientos de los módulos; agregue --symbols para descargar símbolos de PDB y obtener los nombres completos de las funciones.
winapp run .\build\Debug --debug-output --symbols
Importante: Esto asocia winapp como depurador. Windows solo permite un depurador por proceso, por lo que no puedes conectar Visual Studio, VS Code o WinDbg.
Análisis de excepciones almacenadas en WinUI
La mayoría de los errores de WinUI comienzan dentro de un controlador de eventos de XAML y se manifiestan como una stowed exception (0xC000027B) que se vuelve a generar más tarde desde el dispatcher, por lo que la traza de pila habitual ya no apunta a la causa real. Cuando la aplicación que se bloqueó carga Microsoft.UI.Xaml.dll, winapp ejecuta automáticamente una pasada adicional de diagnóstico que decodifica la excepción almacenada y la cadena de despacho nativa de XAML (Microsoft.UI.Xaml → CXcpDispatcher → CoreMessagingXP → host de CLR). El resultado se añade al registro de depuración. No se necesita ninguna marca: se habilita automáticamente para volcados de WinUI. Agregue --symbols para nombres de función totalmente resueltos en la cadena de distribución.
Para que esto funcione, winapp captura el volcado de memoria con el registro de la excepción de terminación permitida (y sus parámetros, que apuntan a la matriz de excepciones permitidas) al tiempo que mantiene el contexto del subproceso de primera oportunidad, por lo que el análisis administrado estándar todavía recupera el marco de usuario original y el pase de evaluación de prioridades puede localizar la excepción permitida.
Este paso hospeda DbgEng con la extensión de JavaScript winDbg del equipo de WinUI. El motor de depuración nativo (dbgeng.dll y otros componentes relacionados) procede de NuGet, y JsProvider.dll —el host de scripting de JavaScript, que no está en NuGet— se obtiene la primera vez que se usa directamente desde la descarga oficial de WinDbg (solo se descargan los pocos cientos de kilobytes necesarios, no el paquete completo). Como JsProvider.dll debe tener la misma compilación que el motor — cargar un proveedor incompatible hace que el depurador se bloquee al iniciarse —, queda fijado al paquete específico de WinDbg cuya compilación coincide con la del motor de NuGet (no a la versión «current» que se va actualizando) y, tras obtenerlo, se comparan ambas compilaciones: cualquier discrepancia se rechaza y se omite el triaje con un motivo claro, en lugar de provocar un bloqueo silencioso. Los paquetes del depurador tienen versiones fijadas y, antes de extraer y cargar cualquiera de sus DLL nativas, se verifican con un hash de contenido SHA-512 integrado en la compilación (y la extensión, con un hash fijado); además, se exige que JsProvider.dll lleve una firma Authenticode válida de Microsoft, comprobada con verificación completa de revocación de la cadena de certificados (recurriendo a una comprobación solo de la firma cuando no se puede acceder sin conexión a los datos de revocación, pero rechazando siempre cualquier certificado revocado). Las descargas se almacenan provisionalmente en un archivo temporal, se comprueban y luego se publican atómicamente en la memoria caché, por lo que una ejecución simultánea nunca observa un archivo DLL parcialmente escrito o no comprobado. En cada ejecución, se vuelven a comprobar los binarios en caché (la firma JsProvider.dll y que coincida con la compilación del motor, y que las DLL del motor sean una imagen PE válida), por lo que una caché truncada o desfasada se autorrepara volviendo a adquirirse, en lugar de fallar en cada ejecución. Esto significa que una fuente reflejada o comprometida no puede sustituir archivos binarios modificados; cualquier error omite la evaluación de prioridades en lugar de cargar código no comprobado. Todo se almacena en caché en el directorio global de winapp, por lo que las ejecuciones posteriores están sin conexión. Si el entorno bloquea esas descargas, instale Herramientas de depuración para Windows (a través del SDK de Windows) o establezca la WINAPP_DBGTOOLS_DIR variable de entorno en un directorio del depurador que ya contiene dbgeng.dll y JsProvider.dll. Cuando se establece WINAPP_DBGTOOLS_DIR, pasa a ser la referencia —solo se consulta ese directorio—, por lo que, si está incompleto, el registro indica el componente concreto que falta (dbgeng.dll o JsProvider.dll, o ambos) en lugar de sugerir que configure una variable que ya está configurada. Cuando el triaje se completa correctamente, la consola muestra un veredicto de una sola línea (el código de error o el mensaje de la excepción almacenada); cuando no se pueden obtener los binarios, se omite la fase de triaje (el análisis estándar de código administrado o nativo se sigue ejecutando), la consola lo indica y el registro explica por qué.
La fase de triaje se ejecuta en un proceso hijo de corta duración. Esto es necesario: el proceso principal de winapp carga la dbghelp.dll del sistema al capturar y analizar el volcado, y el motor moderno dbgeng.dll no puede vincularse con esa copia anterior ya residente; un proceso nuevo proporciona al motor un estado limpio del cargador. La descodificación de las estructuras de excepciones almacenadas también necesita símbolos del sistema operativo (combase.dll), que --symbols descarga del servidor público de símbolos de Microsoft; en las compilaciones cuyos símbolos no se publican allí, la fase de triaje sigue identificando la excepción almacenada, pero no puede expandirla completamente.
Configuración del IDE
VS Code
La extensión WinApp VS Code proporciona un tipo de depuración personalizadowinapp que inicia la aplicación con la identidad del paquete y adjunta el depurador, todo ello desde una sola tecla F5. Instálelo desde Visual Studio Marketplace; su origen y seguimiento de problemas se encuentra en el repositorio microsoft/WinAppVSCE.
Depuración F5 con un solo toque, con identidad
Agregue una winapp configuración de inicio a .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "winapp",
"request": "launch",
"name": "WinApp: Launch and Attach"
}
]
}
Al presionar F5:
- La extensión examina el área de trabajo para ver los directorios de salida de compilación que contienen
.exearchivos. - Seleccione la carpeta de compilación para ejecutar (o establezca
inputFolderpara omitir el mensaje). - Inicia tu aplicación a través de
winapp runpara concederle la identidad del paquete. - Una sesión de depuración secundaria se conecta al proceso en ejecución mediante el depurador especificado.
Una vez que el depurador se conecta, obtiene la experiencia completa de depuración de VS Code: establezca puntos de interrupción haciendo clic en el margen, recorra el código línea a línea (F10), adéntrese en las funciones (F11), inspeccione las variables en el panel Variables y evalúe las expresiones en la Consola de Depuración. La aplicación se ejecuta con la identidad del paquete a lo largo de todo, por lo que las API dependientes de la identidad se comportan exactamente como lo harían en producción.
Importante: El
winapptipo de depuración no compila automáticamente tu proyecto. Después de realizar cambios en el código, recompila antes de presionar F5.
Automatización de compilaciones con preLaunchTask
Para evitar olvidar la recompilación, agregue un preLaunchTask que compile el proyecto antes de cada sesión de depuración:
- Defina una tarea de compilación en
.vscode/tasks.json(por ejemplo, .NET):{ "version": "2.0.0", "tasks": [ { "label": "build", "command": "dotnet", "type": "process", "args": ["build", "${workspaceFolder}"], "problemMatcher": "$msCompile" } ] } - Haga referencia a él en
launch.json:{ "type": "winapp", "request": "launch", "name": "WinApp: Launch and Attach", "preLaunchTask": "build" }
Propiedades de configuración
| Propiedad | Tipo | Predeterminado | Description |
|---|---|---|---|
inputFolder |
string | Ruta de acceso a la carpeta de salida de compilación que contiene los archivos binarios de la aplicación (por ejemplo, ${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621). Si no se establece, se le pedirá que seleccione una carpeta. |
|
manifest |
string | Ruta de acceso a un archivo de manifiesto de AppX (por ejemplo, AppxManifest.xml, Package.appxmanifesto appxmanifest.xml). Si no se establece, la CLI detecta automáticamente desde la carpeta de entrada o el directorio actual. |
|
debuggerType |
string | coreclr |
Depurador subyacente que se va a usar (coreclr, cppvsdbgo node). |
workingDirectory |
string | carpeta del área de trabajo | Directorio de trabajo de la aplicación. |
args |
string | Argumentos de línea de comandos que se van a pasar a la aplicación. | |
outputAppxDirectory |
string | Directorio de salida del paquete de diseño flexible. El valor predeterminado es una carpeta AppX dentro de la carpeta de entrada. |
|
port |
número | 9229 |
(node solo) Puerto utilizado para el servidor de escucha Node.js --inspect y la conexión de adjuntar. Anule cuando el puerto predeterminado ya está en uso. |
Depuradores soportados
debuggerType |
Language | Extensión necesaria |
|---|---|---|
coreclr (valor predeterminado) |
C# /.NET | Kit de desarrollo de C# |
cppvsdbg |
C/C++ | C/C++ |
node |
Node.js / Electron | Integrado |
Ejemplo de un proyecto de C++:
{
"type": "winapp",
"request": "launch",
"name": "WinApp: Launch C++ App",
"debuggerType": "cppvsdbg"
}
Depuración de inicio con Creación de una identidad de depuración
Si necesita depurar el código de inicio desde la primera instrucción, el método de conexión F5 puede ignorar el código inicial. En su lugar, use el comando WinApp: Crear identidad de depuración desde la paleta de comandos (Ctrl+Shift+P) para registrar un paquete disperso para el archivo ejecutable y, a continuación, iniciarlo con el depurador estándar:
{
"name": "Launch (with identity)",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/bin/Debug/net8.0-windows10.0.22621/myapp.exe"
}
Dado que create-debug-identity registra la identidad en el propio archivo ejecutable (exe), la aplicación mantiene su identidad independientemente de cómo se inicie, incluso desde una configuración de lanzamiento típica de VS Code.
Asociación a un proceso en ejecución
Si prefiere iniciar con winapp run desde el terminal y, a continuación, adjuntar, use una configuración de asociación estándar:
{
"name": "Attach to Process",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
Para C++/Rust, use "type": "cppvsdbg" (MSVC) o "type": "lldb" (LLDB):
{
"name": "Attach (C++)",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}"
}
Limpieza
Cuando haya terminado de probar, ejecute WinApp: Anular el registro del paquete desde la paleta de comandos para eliminar los paquetes de desarrollo cargados lateralmente sin salir de VS Code.