C++ 및 CMake에서 winapp CLI 사용

이 가이드에서는 C++ 애플리케이션에서 winapp CLI를 사용하여 패키지 ID로 디버그하고 애플리케이션을 MSIX로 패키지하는 방법을 보여 줍니다.

패키지 ID는 Windows app 모델의 핵심 개념입니다. 이를 통해 애플리케이션은 알림, 보안, AI API 등과 같은 특정 Windows API를 access, 깨끗한 설치/제거 환경 등을 사용할 수 있습니다.

표준 실행 파일(예: 생성된 cmake --build실행 파일)에는 패키지 ID가 없습니다. 이 가이드에서는 디버깅을 위해 추가한 다음 배포용으로 패키지하는 방법을 보여줍니다.

필수 조건

  1. 빌드 도구: CMake에서 지원하는 컴파일러 도구 체인을 사용합니다. 이 예제에서는 Visual Studio 사용합니다. 다음을 사용하여 Community Edition을 설치할 수 있습니다.

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

    설치 후 다시 부팅합니다.

  2. CMake: CMake 설치:

    winget install Kitware.CMake --source winget
    
  3. winapp CLI: winget을 사용하여 winapp CLI를 설치하십시오.

    winget install Microsoft.winappcli --source winget
    

1. 새 C++ 앱 만들기

간단한 C++ 애플리케이션을 만들어 시작합니다. 프로젝트를 위한 새 디렉터리를 만드세요.

mkdir cpp-app
cd cpp-app

main.cpp 기본 "Hello, world!" 프로그램을 사용하여 파일을 만듭니다.

#include <iostream>

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

이제 빌드를 설정하기 위해 CMakeLists.txt 파일을 만듭니다.

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)

빌드하고 실행하여 모든 것이 작동하는지 확인합니다.

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

2. ID를 확인하도록 코드 업데이트

Windows Runtime C++ API를 사용하여 패키지 ID로 실행되는지 확인하도록 앱을 업데이트합니다.

먼저 CMakeLists.txt 업데이트하여 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)

다음으로 다음의 내용을 바꿉니다.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. ID 없이 실행

앱을 다시 빌드하고 실행합니다.

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

"패키지되지 않음"이 표시됩니다. 그러면 패키지 ID 없이 표준 실행 파일이 실행 중임을 확인합니다.

4. winapp CLI를 사용하여 project 초기화

winapp init 명령은 앱 매니페스트, 자산 및 선택적으로 C++ 개발을 위한 Windows App SDK 헤더 등 필요한 모든 것을 설정합니다.

winapp init

프롬프트가 표시되면

  • 패키지 이름: Enter 키를 눌러 기본값 적용(cpp-app)
  • Publisher 이름: Enter 키를 눌러 기본값을 적용하거나 이름을 입력합니다.
  • 버전: Enter 키를 눌러 1.0.0.0 허용
  • 진입점: Enter 키를 눌러 기본값(cpp-app.exe)을 적용합니다.
  • SDK 설정: "안정적인 SDK"를 선택하여 Windows App SDK 다운로드하고 헤더를 생성합니다.

이 명령은 다음을 만듭니다.

  • appxmanifest.xmlAssets 폴더는 앱 ID에 대한 것입니다.
  • Windows App SDK 헤더 및 라이브러리가 있는 .winapp 폴더
  • winapp.yaml SDK 버전을 고정하기 위한 구성 파일

5. ID를 사용하여 디버그

앱을 완전히 패키징하지 않고 ID가 필요한 기능을 테스트하려면 다음을 사용합니다 winapp create-debug-identity.

  1. 실행 파일을 빌드합니다.

    cmake --build build --config Debug
    
  2. 디버그 ID 적용:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. 실행 파일을 실행합니다.

    .\build\Debug\cpp-app.exe
    

이제 다음과 유사한 출력이 표시됩니다.

Package Family Name: cpp-app_12345abcde

디버그 ID 자동화(선택 사항)

빌드 후 명령을 CMakeLists.txt에 추가하여 디버그 아이덴티티를 자동으로 적용하십시오.

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. Windows App SDK 사용(선택 사항)

winapp init 동안 SDK를 설정하도록 선택한 경우, .winapp/include 폴더에서 Windows App SDK 헤더에 접근할 수 있습니다.

CMakeLists.txt 헤더를 포함하도록 업데이트합니다.

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

Windows App 런타임 API를 사용하도록 main.cpp 업데이트합니다.

#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. 필요한 경우 헤더 복원

.winapp 폴더가 자동으로 .gitignore에 추가됩니다. 다른 사용자가 project 복제하는 경우 다음 파일을 복원해야 합니다.

winapp restore
winapp cert generate --if-exists skip

8. MSIX를 사용한 패키지

배포할 준비가 되면 MSIX로 패키지합니다.

  1. 릴리스용 빌드:

    cmake --build build --config Release
    
  2. 패키지 디렉터리 준비:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. 개발 인증서 생성:

    winapp cert generate --if-exists skip
    
  4. 패키지 및 서명:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. 인증서 설치 (관리자 권한으로 실행):

    winapp cert install .\devcert.pfx
    
  6. 설치 및 실행:

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

팁 (조언)

  • 프로덕션 배포를 위해 인증 기관의 코드 서명 인증서를 사용하여 MSIX에 서명합니다.
  • Microsoft Store에서 MSIX에 서명합니다. 제출하기 전에 서명할 필요가 없습니다.
  • 지원하는 각 아키텍처(x64, Arm64)에 대해 별도의 MSIX 패키지가 필요할 수 있습니다.