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.
En esta guía se muestra cómo usar la winapp CLI con una aplicación de C++ para depurar con la identidad del paquete y empaquetar la aplicación como 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 cmake --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
Herramientas de compilación: use una cadena de herramientas del compilador compatible con CMake. En este ejemplo se usa Visual Studio. Puede instalar la edición comunitaria (o actualizarla si ya está instalada):
winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"Reinicie después de la instalación.
CMake: instale CMake (o actualice si ya está instalado):
winget install Kitware.CMake --source wingetCLI de winapp: instale la
winappcli mediante winget (o actualice si ya está instalada):winget install Microsoft.winappcli --source winget
1. Crear una nueva aplicación de C++
Empiece por crear una aplicación sencilla de C++. Crear un nuevo directorio para el proyecto.
mkdir cpp-app
cd cpp-app
Cree un archivo main.cpp con un programa básico "Hello, world!".
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Cree un CMakeLists.txt archivo para configurar la compilación:
cmake_minimum_required(VERSION 3.20)
project(cpp-app)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(cpp-app main.cpp)
Compile y ejecútelo para asegurarse de que todo funciona:
cmake -B build
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
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. Esto nos ayudará a comprobar que la identidad funciona correctamente en pasos posteriores. Usaremos la API de Windows Runtime de C++ para acceder a las API de paquete.
En primer lugar, agregue la siguiente línea al final de la CMakeLists.txt para vincularla con la biblioteca modelo de Aplicación de Windows:
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
A continuación, reemplace todo el contenido de main.cpp 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".
#include <iostream>
#include <windows.h>
#include <appmodel.h>
int main() {
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
std::wstring familyName;
familyName.resize(length);
result = GetCurrentPackageFamilyName(&length, familyName.data());
if (result == ERROR_SUCCESS) {
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
} else {
std::wcout << L"Error retrieving Package Family Name" << std::endl;
}
} else {
// No package identity
std::cout << "Not packaged" << std::endl;
}
return 0;
}
3. Ejecutar sin identidad
Ahora, recompile y ejecute la aplicación como de costumbre:
cmake --build build --config Debug
.\build\Debug\cpp-app.exe
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 winapp init configura todo lo que necesita de una vez: manifiesto de la aplicación, recursos y, opcionalmente, encabezados de SDK de Aplicaciones para Windows para el desarrollo de C++.
Ejecute el siguiente comando y siga las indicaciones:
winapp init .
Cuando se le solicite,
- Nombre del paquete: presione Entrar para aceptar el valor predeterminado (cpp-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.
- Punto de entrada: presione Entrar para aceptar el valor predeterminado (cpp-app.exe)
- Setup SDK: seleccione "SDK estables" para descargar SDK de Aplicaciones para Windows y generar encabezados de C++
Este comando hará lo siguiente:
- Crear
Package.appxmanifest: el manifiesto que define la identidad de la aplicación - Crear la carpeta
Assets— iconos necesarios para el empaquetado MSIX y la publicación en la Tienda - Crear una carpeta
.winappcon encabezados y bibliotecas del SDK de Aplicaciones para Windows - Creación de un
winapp.yamlarchivo de configuración para anclar versiones del SDK
Puede abrir Package.appxmanifest para personalizar aún más las propiedades, como el nombre para mostrar, el publicador y las funcionalidades.
Agregar alias de ejecución (para aplicaciones de consola)
Un alias de ejecución permite a los usuarios ejecutar la aplicación por su nombre desde cualquier terminal (como cpp-app). También permite winapp run --with-alias durante el desarrollo, lo que mantiene la salida de la consola en el terminal actual en lugar de abrir una nueva ventana.
Puede agregar una automáticamente:
winapp manifest add-alias
O manualmente: abra Package.appxmanifest y, si falta, agregue el espacio de nombres uap5 a la etiqueta <Package>, y luego agregue la extensión dentro de <Applications><Application><Extensions>...:
<Package
...
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
+ xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop6 uap10">
...
<Applications>
<Application ...>
...
+ <Extensions>
+ <uap5:Extension Category="windows.appExecutionAlias">
+ <uap5:AppExecutionAlias>
+ <uap5:ExecutionAlias Alias="cpp-app.exe" />
+ </uap5:AppExecutionAlias>
+ </uap5:Extension>
+ </Extensions>
</Application>
</Applications>
</Package>
5. Depurar con identidad
Para probar las características que requieren identidad (como notificaciones) sin empaquetar completamente la aplicación, puede usar winapp run. Esto registra un paquete de diseño flexible (al igual que una instalación MSIX real) e inicia la aplicación en un solo paso. No se necesita ningún certificado ni firma para la depuración.
Compile el archivo ejecutable:
cmake --build build --config DebugEjecute con identidad:
winapp run .\build\Debug --with-alias
La --with-alias marca inicia la aplicación a través de su alias de ejecución para que la salida de la consola permanezca en el terminal actual. Esto requiere el uap5:ExecutionAlias que agregamos en el paso 4.
Sugerencia
winapp run también registra el paquete en el sistema. Este es el motivo por el que MSIX puede aparecer como "ya instalado" al intentar instalarlo más adelante en el paso 8. Use winapp unregister para limpiar los paquetes de desarrollo cuando haya terminado.
Ahora debería ver una salida similar a la siguiente:
Package Family Name: cpp-app_12345abcde
Esto confirma que la aplicación se está ejecutando con una identidad de paquete válida.
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:
winapp create-debug-identity .\build\Debug\cpp-app.exe
.\build\Debug\cpp-app.exe
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.
6. Usar SDK de Aplicaciones para Windows (opcional)
Si ha seleccionado configurar los SDK durante winapp init, ahora tiene acceso a los encabezados de SDK de Aplicaciones para Windows en la carpeta .winapp/include. Esto le proporciona acceso a las API de Windows modernas, como notificaciones, ventanas, inteligencia artificial en el dispositivo, etc. Si solo necesita la identidad del paquete para la distribución, puede ir al paso 7.
Vamos a agregar un ejemplo sencillo que imprime la versión de Aplicación de Windows runtime.
Actualizar CMakeLists.txt
Agregue la siguiente línea al final del CMakeLists.txt para incluir los encabezados de SDK de Aplicaciones para Windows:
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Actualizar main.cpp
Reemplace todo el contenido de main.cpp para usar la API de tiempo de ejecución de aplicaciones de Windows.
#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
int main() {
// Initialize WinRT
winrt::init_apartment();
UINT32 length = 0;
LONG result = GetCurrentPackageFamilyName(&length, nullptr);
if (result == ERROR_INSUFFICIENT_BUFFER) {
// We have a package identity
std::wstring familyName;
familyName.resize(length);
result = GetCurrentPackageFamilyName(&length, familyName.data());
if (result == ERROR_SUCCESS) {
std::wcout << L"Package Family Name: " << familyName.c_str() << std::endl;
// Get Windows App Runtime version using the API
auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
} else {
std::wcout << L"Error retrieving Package Family Name" << std::endl;
}
} else {
std::cout << "Not packaged" << std::endl;
}
return 0;
}
Compilación y ejecución
Vuelva a compilar la aplicación con los encabezados de SDK de Aplicaciones para Windows.
cmake --build build --config Debug
winapp run .\build\Debug --with-alias
Ahora debería ver un resultado similar a:
Package Family Name: cpp-app_12345abcde
Windows App Runtime Version: 1.8-stable (1.8.0)
El directorio />
-
winrt/: encabezados de proyección de C++ de WinRT para acceder a las API de Windows Runtime -
Microsoft.UI.*.h- Encabezados WinUI 3 para componentes de interfaz de usuario modernos -
MddBootstrap.h: arranque de SDK de Aplicaciones para Windows -
WindowsAppSDK-VersionInfo.h- Información de versión - 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. Restaurar encabezados cuando sea necesario
La .winapp carpeta se agrega automáticamente a .gitignore mediante winapp init, por lo que no se comprobará en el control de código fuente. Cuando otros clonen el proyecto, tendrán que restaurar estos archivos antes de compilar.
Configuración manual
Ejecute estos dos comandos después de clonar el repositorio:
# Restore Windows App SDK headers
winapp restore
# Generate development certificate (optional - only if planning to package the app and sideload)
winapp cert generate --if-exists skip
A continuación, puede compilar y ejecutar normalmente con cmake -B build y cmake --build build --config Debug.
Configuración automatizada con CMake
Como alternativa, puede automatizar esto agregando lógica de configuración a CMakeLists.txt. Este es el completo CMakeLists.txt con la automatización, la vinculación adecuada y el estándar mínimo de C++20:
cmake_minimum_required(VERSION 3.20)
project(cpp-app)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Download winapp CLI if not available in PATH
find_program(WINAPP_CLI winapp)
if(NOT WINAPP_CLI)
set(WINAPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.winapp-tools")
set(WINAPP_CLI "${WINAPP_DIR}/winapp.exe")
if(NOT EXISTS "${WINAPP_CLI}")
message(STATUS "Downloading winapp CLI...")
# Determine architecture
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
set(WINAPP_ARCH "arm64")
else()
set(WINAPP_ARCH "x64")
endif()
# Download and extract
set(WINAPP_ZIP "${CMAKE_CURRENT_BINARY_DIR}/winappcli.zip")
file(DOWNLOAD
"https://github.com/microsoft/WinAppCli/releases/latest/download/winappcli-${WINAPP_ARCH}.zip"
"${WINAPP_ZIP}"
SHOW_PROGRESS
)
file(ARCHIVE_EXTRACT INPUT "${WINAPP_ZIP}" DESTINATION "${WINAPP_DIR}")
file(REMOVE "${WINAPP_ZIP}")
message(STATUS "winapp CLI downloaded to ${WINAPP_DIR}")
endif()
endif()
# Automatically restore Windows App SDK headers and generate certificate if needed
# This runs once during CMake configuration, not on every build
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include")
message(STATUS "Restoring Windows App SDK headers...")
execute_process(
COMMAND "${WINAPP_CLI}" restore
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE RESTORE_RESULT
)
if(NOT RESTORE_RESULT EQUAL 0)
message(WARNING "Failed to restore Windows App SDK. Run 'winapp restore' manually.")
endif()
endif()
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/devcert.pfx")
message(STATUS "Generating development certificate...")
execute_process(
COMMAND "${WINAPP_CLI}" cert generate --if-exists skip
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE CERT_RESULT
)
if(NOT CERT_RESULT EQUAL 0)
message(WARNING "Failed to generate certificate. Run 'winapp cert generate' manually.")
endif()
endif()
add_executable(cpp-app main.cpp)
# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)
# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)
Con esta configuración:
- Cuando alguien clona el repositorio y ejecuta
cmake -B build, winapp se descarga automáticamente si no se encuentra en PATH. - Los encabezados y el certificado de SDK de Aplicaciones para Windows se restauran automáticamente
- Los comandos solo se ejecutan una vez durante la configuración (no en todas las compilaciones) porque comprueban si los archivos ya existen.
- Si se produce un error en los comandos, CMake muestra una advertencia con instrucciones para ejecutarlos manualmente.
- La winapp descargada se almacena en
.winapp-tools/(agréguelo a.gitignoresi es necesario)
8. Paquete con MSIX
Una vez que esté listo para distribuir la aplicación, puede empaquetarla como MSIX mediante el mismo manifiesto. MSIX proporciona una instalación o desinstalación limpia, actualizaciones automáticas y una experiencia de instalación de confianza.
Preparar el directorio de paquetes
En primer lugar, compile la aplicación en modo de versión para obtener un rendimiento óptimo:
cmake --build build --config Release
A continuación, cree un directorio con solo los archivos necesarios para la distribución y copie el archivo ejecutable de versión:
mkdir dist
copy .\build\Release\cpp-app.exe .\dist\
Generación de un certificado de desarrollo
Los paquetes MSIX deben estar firmados. Para las pruebas locales, genere un certificado de desarrollo autofirmado:
winapp cert generate --if-exists skip
Sugerencia
El emisor del certificado debe coincidir con el Publisher en tu Package.appxmanifest. El cert generate comando lo lee automáticamente desde el manifiesto.
Firmar y empaquetar
Ahora puede empaquetar y firmar:
# package and sign the app with the generated certificate
winapp pack .\dist --cert .\devcert.pfx
Sugerencia
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 generado .msix estará en el directorio actual.
Instalación del certificado
Para poder instalar el paquete MSIX, debe confiar en el certificado de desarrollo en el equipo. Ejecute este comando como administrador (solo tiene que hacerlo una vez por certificado):
winapp cert install .\devcert.pfx
Instalación y ejecución
Sugerencia
Si usó winapp run en el paso 5, es posible que el paquete ya esté registrado en el sistema. Use winapp unregister primero para quitar el registro de desarrollo y, a continuación, instale el paquete de versión.
El winapp pack comando genera el archivo MSIX en el directorio raíz del proyecto. Instale el paquete haciendo doble clic en el archivo generado .msix o mediante PowerShell:
Add-AppxPackage .\cpp-app_1.0.0.0_x64.msix
Sugerencia
El nombre de archivo MSIX incluye la versión y la arquitectura (por ejemplo, cpp-app_1.0.0.0_arm64.msix). Compruebe el directorio para ver el nombre de archivo exacto.
Ahora puede ejecutar la aplicación desde cualquier lugar del terminal escribiendo:
cpp-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
- 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.
- El servicio Firma de confianza de Azure es una excelente manera de administrar los certificados de forma segura e integrar el inicio de sesión en la canalización de CI/CD.
- El Microsoft Store firmará el MSIX por usted, no es necesario firmar antes del envío.
- Es posible que tenga que crear varios paquetes MSIX, uno para cada arquitectura que admita (x64, Arm64). Configure CMake con las marcas de generador y arquitectura adecuadas.
Pasos siguientes
- Distribute a través de winget: Envíe su MSIX al repositorio Windows Administrador de paquetes Community
-
Publicar en Microsoft Store: Utilice
winapp storepara enviar su paquete - Configurar CI/CD: Usa la acción de GitHub para automatizar el empaquetado en la tubería
- Explore Windows APIs: Con la identidad del paquete, ahora puede usar notificaciones, IA en el dispositivo y otras APIs dependientes de la identidad