Uso de la CLI de winapp con .NET

Esta guía debe funcionar para la mayoría de los tipos de proyecto .NET. Los pasos se han probado con proyectos basados en la consola y en la interfaz de usuario, como WPF. Para ver ejemplos de trabajo, consulte los ejemplos dotnet-app (consola) y wpf-app (WPF) en la carpeta samples.

En esta guía se demuestra cómo utilizar la CLI de winapp con una aplicación de .NET para depurar utilizando la identidad del paquete y empaquetar su aplicación como un MSIX.

La identidad del paquete es un concepto básico en el modelo de Windows app. Permite a la aplicación acceder a api de Windows específicas (como notificaciones, seguridad, API de IA, etc.), tener una experiencia de instalación o desinstalación limpia, etc.

Un archivo ejecutable estándar (como uno creado con dotnet build) no tiene la identidad del paquete. Esta guía muestra cómo agregarlo para depuración y luego empaquetarlo para su distribución.

Prerrequisitos

  1. .NET SDK: instale el SDK de .NET (requiere un reinicio después de la instalación):

    winget install Microsoft.DotNet.SDK.10 --source winget
    
  2. CLI de winapp: instale la winapp herramienta mediante winget (o actualice si ya está instalada):

    winget install Microsoft.winappcli --source winget
    

1. Crear una nueva aplicación de .NET

Empiece por crear una aplicación de consola de .NET sencilla:

dotnet new console -n dotnet-app
cd dotnet-app

Ejecútelo para asegurarse de que todo funciona:

dotnet run

La salida debe ser "Hello, World!"

2. Actualizar código para comprobar la identidad

Actualizaremos la aplicación para comprobar si se ejecuta con la identidad del paquete. Usaremos la API de Windows Runtime para acceder a las API de paquete.

En primer lugar, actualice el archivo project para tener como destino una versión específica de Windows SDK. Abra dotnet-app.csproj y cambie el TargetFramework para incluir la versión del SDK de Windows:

  <TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>

Esto le proporciona acceso a Windows Runtime API sin necesidad de paquetes adicionales.

Ahora reemplace el contenido de Program.cs por el código siguiente. Este código intenta recuperar la identidad del paquete actual mediante la API de Windows Runtime. Si se realiza correctamente, imprime el nombre de familia del paquete; de lo contrario, imprime "No empaquetado".

using Windows.ApplicationModel;

try
{
    var package = Package.Current;
    var familyName = package.Id.FamilyName;
    Console.WriteLine($"Package Family Name: {familyName}");
}
catch (InvalidOperationException)
{
    // Thrown when app doesn't have package identity
    Console.WriteLine("Not packaged");
}

3. Ejecutar sin identidad

Ahora, ejecute la aplicación como de costumbre:

dotnet run

Debería ver el resultado "No empaquetado". Esto confirma que el ejecutable estándar se está ejecutando sin ninguna identidad de paquete.

4. Inicializar Project con la CLI de winapp

El comando detecta automáticamente archivos /> TargetFramework, agrega los paquetes NuGet necesarios, genera el manifiesto de la aplicación y los recursos.

Ejecute el siguiente comando y siga las indicaciones:

winapp init

Cuando se le solicite,

  • Nombre del paquete: presione Entrar para aceptar el valor predeterminado (dotnet-app)
  • Nombre del editor: Presione Intro para aceptar el valor predeterminado o escriba su nombre.
  • Versión: presione Entrar para aceptar 1.0.0.0.
  • Description: presione Entrar para aceptar el valor predeterminado (Windows Aplicación) o escriba una descripción.
  • SDK de Aplicaciones para Windows configuración: Seleccione Estable, Versión preliminar o Experimental (determina qué versión de SDK de Aplicaciones para Windows se agrega)
  • TargetFramework update: Si la TargetFramework no incluye una versión de SDK de Windows compatible, se le pedirá que la actualice (por ejemplo, para net10.0-windows10.0.26100.0).
  • Modo de desarrollador: si se le pide "Modo de desarrollador", puede activarlo si lo desea, pero tenga en cuenta que requiere privilegios administrativos.

Este comando hará lo siguiente:

  • Actualice el TargetFramework en su .csproj a un TFM compatible con Windows (si es necesario)
  • Agregue Microsoft.WindowsAppSDK, Microsoft.Windows.SDK.BuildTools y Microsoft.Windows.SDK.BuildTools.WinApp referencias del paquete NuGet a la .csproj
  • Crear la carpeta Package.appxmanifest y Assets para la identidad de la aplicación

Nota:

A diferencia de los proyectos nativos o de C++, el flujo de .NET no crea un archivo winapp.yaml. Los paquetes NuGet se administran directamente a través de .csproj. Use dotnet restore para restaurar paquetes después de la clonación.

Puede abrir Package.appxmanifest para personalizar aún más las propiedades, como el nombre para mostrar, el publicador y las funcionalidades.

Para comprobar que los paquetes se agregaron al proyecto:

dotnet list package

Debería ver Microsoft.WindowsAppSDK y Microsoft.Windows.SDK.BuildTools en la salida.

Agregar alias de ejecución (para aplicaciones de consola)

Dado que estamos creando una aplicación de consola, es necesario asegurarnos de mantener dotnet run la salida de la consola en el terminal actual. De forma predeterminada, dotnet run inicia la aplicación empaquetada a través de la activación de AUMID, que abre una nueva ventana, y la ventana se cierra inmediatamente cuando finaliza la aplicación de consola, tragándose cualquier salida.

Para corregirlo, agregarás un alias de ejecución al manifiesto e indicarás a la integración que realice la ejecución a través de ese alias en su lugar.

Omita este paso si está construyendo una aplicación de interfaz de usuario (UI) (WPF, WinForms, WinUI). Esas aplicaciones renderizan su propia ventana, por lo que el inicio predeterminado de AUMID es lo que necesitas.

  1. Agregue el alias de ejecución al manifiesto:

    winapp manifest add-alias
    

    Esto agrega un uap5:ExecutionAlias a Package.appxmanifest (predeterminando al nombre del ejecutable de tu proyecto) para que la aplicación se pueda iniciar por nombre desde un terminal.

  2. Indique a la dotnet run integración que utilice el alias. Abra dotnet-app.csproj y agregue lo siguiente dentro de cualquiera <PropertyGroup> (o cree un nuevo <PropertyGroup> si es necesario):

    <WinAppRunUseExecutionAlias>true</WinAppRunUseExecutionAlias>
    

    Con esta propiedad configurada, dotnet run inicia la aplicación mediante su alias de ejecución y hereda el stdin/stdout/stderr del terminal actual, para que pueda ver la salida de la consola en línea.

5. Depurar con identidad

Dado que winapp init agregó el paquete NuGet Microsoft.Windows.SDK.BuildTools.WinApp al proyecto, puede ejecutar simplemente:

dotnet run

Esto invoca automáticamente winapp run en segundo plano: crear un paquete de diseño flexible, registrarlo con Windows e iniciar la aplicación con una identidad de paquete completa.

Nota:

Es posible que vea advertencias de vulnerabilidad de NuGet (NU1900) sobre los orígenes de paquetes. Estos se pueden ignorar con seguridad, ya que no afectan a la compilación.

Debería mostrarse una salida similar a esta:

Package Family Name: dotnet-app_12345abcde

Esto confirma que la aplicación se está ejecutando con una identidad de paquete válida.

Alternativa: Manual winapp run

Si no ha usado winapp init (o quitado el paquete NuGet), puede compilar y ejecutar manualmente:

dotnet build -c Debug
winapp run .\bin\Debug\net10.0-windows10.0.26100.0

Para volver a agregar el paquete NuGet: dotnet add package Microsoft.Windows.SDK.BuildTools.WinApp --prerelease

Sugerencia

Para deshabilitar la integración automática dotnet run , agregue <EnableWinAppRunSupport>false</EnableWinAppRunSupport> a .csproj. Consulte la documentación de soporte técnico de dotnet run para ver las opciones de personalización.

Alternativa: identidad del paquete disperso

Si necesita un comportamiento de paquete disperso específicamente (identidad sin copiar archivos), puede usar create-debug-identity en su lugar. Esto registra un paquete disperso que apunta a su exe en lugar de crear un diseño flexible:

winapp create-debug-identity .\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe

A continuación, ejecute el archivo ejecutable directamente (no use dotnet run como podría recompilar o sobrescribir el archivo):

.\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe

Alternativa: objetivo manual de MSBuild

Si prefiere no usar el paquete NuGet, puede agregar un objetivo de MSBuild personalizado que se ejecute create-debug-identity después de las compilaciones Debug. Añada esto a su archivo .csproj al final, justo antes de la etiqueta de cierre </Project>:

  <!-- Automatically apply debug identity after Debug builds -->
  <Target Name="ApplyDebugIdentity" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="winapp create-debug-identity &quot;$(TargetDir)$(TargetName).exe&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          IgnoreExitCode="false" />
  </Target>

Con esta configuración, dotnet build aplica la identidad de depuración y puede ejecutar el archivo ejecutable directamente. Tenga en cuenta que dotnet run puede volver a generar y sobrescribir la identidad, por lo que ejecute el exe manualmente después de la compilación.

Sugerencia

Para obtener flujos de trabajo de depuración avanzados (adjuntar depuradores, configuración del IDE, depuración de inicio), consulte la Guía de depuración.

Cuándo omitir esto: si prefiere el control explícito sobre cuándo se aplica la identidad, o si está trabajando en código que no necesita identidad para la mayoría del ciclo de desarrollo, el enfoque manual anterior puede ser más sencillo.

6. Usar SDK de Aplicaciones para Windows (opcional)

El SDK de Aplicaciones para Windows proporciona acceso a las API de Windows modernas más allá de lo que proporciona el SDK de Windows base, cosas como el sistema de notificaciones, las API de ventanas, la administración del ciclo de vida de las aplicaciones y la inteligencia artificial en el dispositivo. Si la aplicación necesita cualquiera de estas funcionalidades, este paso es para usted. Si solo necesita la identidad del paquete para la distribución, puede ir al paso 7.

Si ejecutó winapp init (Paso 4), Microsoft.WindowsAppSDK ya se ha agregado como referencia de biblioteca NuGet a su .csproj. Puede comprobar con dotnet list package. Si omitió la configuración del SDK durante init o necesita agregarlo manualmente, ejecute lo siguiente:

dotnet add package Microsoft.WindowsAppSDK

Actualizar Program.cs

Reemplace todo el contenido de Program.cs por el código siguiente, que agrega una comprobación de versión en tiempo de ejecución de Aplicación de Windows:

using Windows.ApplicationModel;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var package = Package.Current;
            var familyName = package.Id.FamilyName;
            Console.WriteLine($"Package Family Name: {familyName}");
            
            // Get Windows App Runtime version using the API
            var runtimeVersion = Microsoft.Windows.ApplicationModel.WindowsAppRuntime.RuntimeInfo.AsString;
            Console.WriteLine($"Windows App Runtime Version: {runtimeVersion}");
        }
        catch (InvalidOperationException)
        {
            // Thrown when app doesn't have package identity
            Console.WriteLine("Not packaged");
        }
    }
}

Compilación y ejecución

Vuelva a generar y ejecute la aplicación con SDK de Aplicaciones para Windows. Dado que hemos agregado WinAppSDK, es necesario volver a registrar la identidad para que winapp agregue la dependencia en tiempo de ejecución. Si agregó el paquete NuGet de WinApp (recomendado), simplemente ejecute dotnet run. De lo contrario (reemplace por dotnet-app el nombre del proyecto):

dotnet build -c Debug
winapp run .\bin\Debug\net10.0-windows10.0.26100.0

Ahora debería ver un resultado similar a:

Package Family Name: dotnet-app.debug_12345abcde
Windows App Runtime Version: 8000.770.947.0

El paquete NuGet de SDK de Aplicaciones para Windows incluye todos los ensamblados necesarios para acceder a las API de Windows modernas, entre las que se incluyen:

  • Notificaciones y iconos dinámicos
  • Ciclo de vida de ventanas y aplicaciones
  • Notificaciones push
  • Y muchos más componentes de SDK de Aplicaciones para Windows

Para obtener un uso de SDK de Aplicaciones para Windows más avanzado, consulte la documentación de SDK de Aplicaciones para Windows.

7. Paquete con MSIX

Una vez que esté listo para distribuir la aplicación, puede empaquetarla como MSIX mediante el mismo manifiesto.

Compilación para lanzamiento

En primer lugar, compile la aplicación en modo de versión para obtener un rendimiento óptimo:

dotnet build -c Release

Nota:

Es posible que vea advertencias de vulnerabilidad de NuGet (NU1900). Se pueden ignorar y no afectan al resultado de la compilación.

Generación de un certificado de desarrollo

Antes de empaquetar, necesita un certificado de desarrollo para firmar. Genere uno si aún no lo ha hecho:

winapp cert generate --if-exists skip

Firmar y empaquetar

Ahora puede empaquetar y firmar. Apunte el comando pack a la carpeta de salida de compilación (reemplace dotnet-app y la ruta de acceso de TFM por los valores del proyecto):

# package and sign the app with the generated certificate
winapp pack .\bin\Release\net10.0-windows10.0.26100.0 --manifest .\Package.appxmanifest --cert .\devcert.pfx 

Nota: El pack comando usa automáticamente Package.appxmanifest desde el directorio actual y lo copia en la carpeta de destino antes de empaquetar. El archivo .msix generado estará en el directorio actual.

Instalación del certificado

Para poder instalar el paquete MSIX, debe instalar el certificado de desarrollo. Ejecute este comando como administrador:

winapp cert install .\devcert.pfx

Instalación y ejecución

Instale el paquete haciendo doble clic en el archivo *.msix generado.

Ahora puede ejecutar la aplicación desde cualquier lugar del terminal escribiendo:

dotnet-app

Debería ver la salida "Nombre de familia de paquete", confirmando que está instalada y en ejecución con la identidad.

Sugerencia

Si necesita volver a empaquetar la aplicación (por ejemplo, después de realizar cambios en el código), incremente Version en su Package.appxmanifest antes de volver a ejecutar winapp pack. Windows requiere un número de versión superior para actualizar un paquete instalado.

Tips

  1. Una vez que esté listo para su distribución, puede firmar su MSIX con un certificado de firma de código de una Autoridad de Certificación para que los usuarios no tengan que instalar un certificado autofirmado.
  2. El Microsoft Store firmará el MSIX por usted, no es necesario firmar antes del envío.
  3. Es posible que tenga que crear varios paquetes MSIX, uno para cada arquitectura que admita (x64, Arm64). Use la -r marca con dotnet build para establecer como destino arquitecturas específicas: dotnet build -c Release -r win-x64 o dotnet build -c Release -r win-arm64.

Automatización del empaquetado MSIX (opcional)

Para automatizar el empaquetado MSIX como parte de las compilaciones de liberación, agregue este objetivo al archivo .csproj (puede agregarlo junto con el objetivo de identidad de depuración):

  <!-- Automatically package as MSIX after Release builds -->
  <Target Name="PackageMsix" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
    <!-- Package and sign directly from build output -->
    <Exec Command="winapp pack &quot;$(TargetDir.TrimEnd('\'))&quot; --cert &quot;$(ProjectDir)devcert.pfx&quot;" 
          WorkingDirectory="$(ProjectDir)" 
          IgnoreExitCode="false" />
  </Target>

Con esta configuración:

  • La compilación en modo de versión (dotnet build -c Release) creará automáticamente el paquete MSIX.
  • El MSIX se empaqueta y firma con el certificado de desarrollo.
  • El archivo final .msix estará en la raíz del proyecto.

También puede crear una configuración personalizada (por ejemplo, PackagedRelease) modificando la condición en '$(Configuration)' == 'PackagedRelease'.

Pasos siguientes