Compartir a través de


Uso de la CLI de Winapp con C++ y CMake

En esta guía se muestra cómo usar la CLI de winapp 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 tu aplicación acceder a APIs específicas de Windows (como notificaciones, seguridad, APIs de IA, etc.), tener una experiencia de instalación y 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

  1. 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 community con:

    winget install --id Microsoft.VisualStudio.Community --source winget --override "--add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --passive --wait"
    

    Reinicie después de la instalación.

  2. CMake: Instale CMake:

    winget install Kitware.CMake --source winget
    
  3. CLI de winapp: Instale el CLI mediante Winget:

    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

2. Actualización del código para comprobar la identidad

Actualice la aplicación para comprobar si se ejecuta con la identidad del paquete mediante la API de C++ de Windows Runtime.

En primer lugar, actualice la CMakeLists.txt para vincularla a la biblioteca de modelos de Windows App:

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)

# Link Windows Runtime libraries
target_link_libraries(cpp-app PRIVATE WindowsApp.lib OneCoreUap.lib)

A continuación, reemplace el contenido de main.cpp:

#include <iostream>
#include <windows.h>
#include <appmodel.h>

int main() {
    UINT32 length = 0;
    LONG result = GetCurrentPackageFamilyName(&length, nullptr);

    if (result == ERROR_INSUFFICIENT_BUFFER) {
        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 {
        std::cout << "Not packaged" << std::endl;
    }

    return 0;
}

3. Ejecutar sin identidad

Recompile y ejecute la aplicación:

cmake --build build --config Debug
.\build\Debug\cpp-app.exe

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

4. Inicie el proyecto con la CLI de winapp

El comando winapp init configura todo lo que necesita: manifiesto de aplicación, recursos y, opcionalmente, Windows App SDK encabezados para el desarrollo de C++.

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 Windows App SDK y generar encabezados

Este comando crea:

  • appxmanifest.xml y Assets son carpetas para la identidad de su aplicación
  • Una carpeta .winapp con encabezados y bibliotecas de Windows App SDK
  • Un winapp.yaml archivo de configuración para anclar versiones del SDK

5. Depurar con identidad

Para probar las características que requieren identidad sin empaquetar completamente la aplicación, use winapp create-debug-identity:

  1. Compile el archivo ejecutable:

    cmake --build build --config Debug
    
  2. Aplicar la identidad de depuración:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Ejecute el archivo ejecutable:

    .\build\Debug\cpp-app.exe
    

Ahora debería ver una salida similar a la siguiente:

Package Family Name: cpp-app_12345abcde

Automatizar identidad de depuración (opcional)

Agregue un comando de post-compilación a CMakeLists.txt para aplicar automáticamente la identidad de depuración:

add_custom_command(TARGET cpp-app POST_BUILD
    COMMAND $<$<CONFIG:Debug>:winapp>
            $<$<CONFIG:Debug>:create-debug-identity>
            $<$<CONFIG:Debug>:$<TARGET_FILE:cpp-app>>
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMAND_EXPAND_LISTS
    COMMENT "Applying debug identity to executable..."
)

6. Uso de Windows App SDK (opcional)

Si ha seleccionado configurar los SDKs durante winapp init, tiene acceso a los encabezados del Windows App SDK en la carpeta .winapp/include.

Actualice su CMakeLists.txt para incluir las cabeceras:

# Add Windows App SDK include directory
target_include_directories(cpp-app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.winapp/include)

Actualice main.cpp para usar la API de Windows App Runtime.

#include <iostream>
#include <windows.h>
#include <appmodel.h>
#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>

int main() {
    winrt::init_apartment();

    UINT32 length = 0;
    LONG result = GetCurrentPackageFamilyName(&length, nullptr);

    if (result == ERROR_INSUFFICIENT_BUFFER) {
        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;

            auto runtimeVersion = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::RuntimeInfo::AsString();
            std::wcout << L"Windows App Runtime Version: " << runtimeVersion.c_str() << std::endl;
        }
    } else {
        std::cout << "Not packaged" << std::endl;
    }

    return 0;
}

7. Restaurar encabezados cuando sea necesario

La .winapp carpeta se agrega automáticamente a .gitignore. Cuando otros clonen el project, deben restaurar estos archivos:

winapp restore
winapp cert generate --if-exists skip

8. Paquete con MSIX

Una vez que esté listo para distribuirse, empaquete como MSIX:

  1. Compilación para lanzamiento:

    cmake --build build --config Release
    
  2. Prepare el directorio del paquete:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Genere un certificado de desarrollo:

    winapp cert generate --if-exists skip
    
  4. Empaquetar y firmar:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Instale el certificado (ejecute como administrador):

    winapp cert install .\devcert.pfx
    
  6. Instale y ejecute:

    Add-AppxPackage .\cpp-app.msix
    cpp-app
    

Sugerencia

  • Firme su MSIX con un certificado de firma de código de una entidad de certificación para la distribución de producción.
  • La Microsoft Store firma el MSIX por ti, no es necesario firmar antes de la submisión.
  • Es posible que necesite paquetes MSIX independientes para cada arquitectura que admita (x64, Arm64).