Compartilhar via


Usando a CLI do winapp com C++ e CMake

Este guia demonstra como usar a interface de linha de comando (CLI) do winapp com um aplicativo C++ para depurar utilizando a identidade do pacote e empacotar seu aplicativo como um arquivo MSIX.

A identidade do pacote é um conceito básico no modelo de Windows app. Ele permite que seu aplicativo acesse APIs específicas do Windows (como Notificações, Segurança, APIs de IA etc.), e tenha uma experiência de instalação/desinstalação limpa, entre outras funcionalidades.

Um executável padrão (como um criado com cmake --build) não tem a identidade do pacote. Este guia mostra como adicionar para depuração e, em seguida, empacotar para distribuição.

Pré-requisitos

  1. Ferramentas de Build: use um conjunto de ferramentas do compilador com suporte do CMake. Este exemplo usa Visual Studio. Você pode instalar a edição da comunidade com:

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

    Reinicialize após a instalação.

  2. CMake: instalar o CMake:

    winget install Kitware.CMake --source winget
    
  3. CLI do winapp: instale a winapp CLI utilizando o winget:

    winget install Microsoft.winappcli --source winget
    

1. Criar um novo aplicativo C++

Comece criando um aplicativo C++ simples. Crie um novo diretório para seu project:

mkdir cpp-app
cd cpp-app

Crie um main.cpp arquivo com um programa básico "Olá, mundo!":

#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

Crie um CMakeLists.txt arquivo para configurar o build:

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)

Crie e execute-o para garantir que tudo esteja funcionando:

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

2. Atualizar código para verificar a identidade

Atualize o aplicativo para verificar se ele está em execução com a identidade do pacote usando a API Windows Runtime C++.

Primeiro, atualize o CMakeLists.txt para vincular-se à 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)

Em seguida, substitua o conteúdo 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. Executar sem identificação

Recompile e execute o aplicativo:

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

Você deve ver "Não empacotado". Isso confirma que o executável padrão está em execução sem nenhuma identidade de pacote.

4. Inicie o projeto com a CLI do winapp

O comando winapp init configura tudo o que você precisa: manifesto do aplicativo, ativos e, opcionalmente, cabeçalhos do Windows App SDK para desenvolvimento em C++.

winapp init

Quando solicitado:

  • Nome do pacote: Pressione Enter para aceitar o padrão (cpp-app)
  • Nome do publicador: pressione Enter para aceitar o valor padrão ou insira seu nome
  • Versão: Pressione Enter para aceitar 1.0.0.0
  • Ponto de entrada: pressione Enter para aceitar o padrão (cpp-app.exe)
  • Setup SDKs: selecione "SDKs estáveis" para baixar Windows App SDK e gerar cabeçalhos

Este comando cria:

  • appxmanifest.xml e Assets pasta para a identidade do aplicativo
  • Uma pasta .winapp com cabeçalhos e bibliotecas Windows App SDK
  • Um winapp.yaml arquivo de configuração para fixar versões do SDK

5. Depurar com identidade

Para testar os recursos que exigem identidade sem empacotar totalmente o aplicativo, use winapp create-debug-identity:

  1. Crie o executável:

    cmake --build build --config Debug
    
  2. Aplicar identidade de depuração:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Execute o executável:

    .\build\Debug\cpp-app.exe
    

Agora você deve ver uma saída semelhante a:

Package Family Name: cpp-app_12345abcde

Automatizando a identidade de debug (opcional)

Adicione um comando pós-compilação à sua CMakeLists.txt para aplicar automaticamente a identidade de depuração:

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. Usando Windows App SDK (opcional)

Se você tiver selecionado configurar os SDKs durante winapp init, terá acesso aos cabeçalhos do Windows App SDK na pasta .winapp/include.

Atualize o seu CMakeLists.txt para incluir os cabeçalhos:

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

Atualize main.cpp para usar a API 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 cabeçalhos quando necessário

A .winapp pasta é adicionada automaticamente a .gitignore. Quando outras pessoas clonam sua project, elas precisam restaurar esses arquivos:

winapp restore
winapp cert generate --if-exists skip

8. Pacote com MSIX

Quando estiver pronto para distribuir, empacote como MSIX:

  1. Compilar para lançamento:

    cmake --build build --config Release
    
  2. Preparar o diretório do pacote:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Gerar um certificado de desenvolvimento:

    winapp cert generate --if-exists skip
    
  4. Empacotar e assinar:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Instalar o certificado (executar como administrador):

    winapp cert install .\devcert.pfx
    
  6. Instalar e executar:

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

Dica

  • Assine seu MSIX com um certificado de assinatura de código de uma Autoridade de Certificação para distribuição em produção.
  • A Microsoft Store assina o MSIX para você, não é necessário assinar antes do envio.
  • Talvez você precise de pacotes MSIX separados para cada arquitetura compatível (x64, Arm64).