Menggunakan CLI winapp dengan C++ dan CMake

Panduan ini menunjukkan cara menggunakan CLI winapp dengan aplikasi C++ untuk men-debug dengan identitas paket dan mengemas aplikasi Anda sebagai MSIX.

Identitas paket adalah konsep inti dalam model Windows app. Ini memungkinkan aplikasi Anda untuk mengakses API Windows tertentu (seperti Pemberitahuan, Keamanan, API AI, dll.), merasakan pengalaman pemasangan/penghapusan instalasi yang lebih bersih, dan banyak lagi.

Executable standar (seperti yang dibuat dengan cmake --build) tidak memiliki identitas paket. Panduan ini menunjukkan cara menambahkannya untuk penelusuran kesalahan lalu mengemasnya untuk didistribusikan.

Prasyarat

  1. Build Tools: Gunakan toolchain pengkompilasi yang didukung oleh CMake. Contoh ini menggunakan Visual Studio. Anda dapat menginstal edisi komunitas dengan:

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

    Reboot setelah penginstalan.

  2. CMake: Instal CMake:

    winget install Kitware.CMake --source winget
    
  3. winapp CLI: Instal winapp CLI melalui winget:

    winget install Microsoft.winappcli --source winget
    

1. Buat aplikasi C++ baru

Mulailah dengan membuat aplikasi C++ sederhana. Buat direktori baru untuk project Anda:

mkdir cpp-app
cd cpp-app

Buat main.cpp file dengan program dasar "Halo, dunia!":

#include <iostream>

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

Buat CMakeLists.txt file untuk mengonfigurasi 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)

Kompilasi dan jalankan untuk memastikan agar berfungsi dengan baik:

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

2. Perbarui kode untuk memeriksa identitas

Perbarui aplikasi untuk memeriksa apakah aplikasi berjalan dengan identitas paket menggunakan API Windows Runtime C++.

Pertama, perbarui CMakeLists.txt Anda untuk menautkan ke pustaka Windows App Model.

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)

Selanjutnya, ganti isi dari 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. Jalankan tanpa identitas

Bangun ulang dan jalankan aplikasi:

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

Anda akan melihat "Tidak dibungkus". Ini mengonfirmasi bahwa executable standar berjalan tanpa identitas paket apa pun.

4. Inisialisasi project dengan winapp CLI

Perintah winapp init menyiapkan semua yang Anda butuhkan: manifes aplikasi, aset, dan secara opsional Windows App SDK header untuk pengembangan C++.

winapp init

Ketika diminta:

  • Nama paket: Tekan Enter untuk menerima default (cpp-app)
  • Nama penerbit: Tekan Enter untuk menerima pengaturan standar atau masukkan nama Anda
  • Versi: Tekan Enter untuk menerima 1.0.0.0
  • Titik masuk: Tekan Enter untuk menerima default (cpp-app.exe)
  • Setup SDK: Pilih "SDK Stabil" untuk mengunduh Windows App SDK dan menghasilkan header

Perintah ini membuat:

  • Untuk identitas aplikasi Anda, folder appxmanifest.xml dan Assets
  • Folder .winapp yang berisi header dan pustaka Windows App SDK
  • winapp.yaml File konfigurasi untuk menyematkan versi SDK

5. Debug menggunakan identitas

Untuk menguji fitur yang memerlukan identitas tanpa sepenuhnya mengemas aplikasi, gunakan winapp create-debug-identity:

  1. Buat executable:

    cmake --build build --config Debug
    
  2. Terapkan identitas debug:

    winapp create-debug-identity .\build\Debug\cpp-app.exe
    
  3. Jalankan executable:

    .\build\Debug\cpp-app.exe
    

Anda sekarang akan melihat output yang mirip dengan:

Package Family Name: cpp-app_12345abcde

Otomatisasi identitas debug (opsional)

Tambahkan perintah pasca-pembangunan ke CMakeLists.txt Anda untuk menerapkan identitas debug secara otomatis.

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. Menggunakan Windows App SDK (opsional)

Jika Anda memilih untuk menyiapkan SDK selama winapp init, Anda memiliki akses ke tajuk Windows App SDK di folder .winapp/include.

Perbarui Anda CMakeLists.txt untuk menyertakan header:

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

Perbarui main.cpp untuk menggunakan WINDOWS APP Runtime API:

#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. Pulihkan header saat diperlukan

Folder .winapp secara otomatis ditambahkan ke .gitignore. Ketika orang lain mengkloning project Anda, mereka perlu memulihkan file-file ini:

winapp restore
winapp cert generate --if-exists skip

8. Paket dengan MSIX

Setelah Anda siap mendistribusikan, kemas sebagai MSIX.

  1. Bangun untuk rilis:

    cmake --build build --config Release
    
  2. Siapkan direktori paket:

    mkdir dist
    copy .\build\Release\cpp-app.exe .\dist\
    
  3. Buat sertifikat pengembangan:

    winapp cert generate --if-exists skip
    
  4. Paket dan tanda tangan:

    winapp pack .\dist --cert .\devcert.pfx
    
  5. Instal sertifikat (jalankan sebagai administrator):

    winapp cert install .\devcert.pfx
    
  6. Instal dan jalankan:

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

Tip

  • Tanda tangani MSIX Anda dengan sertifikat penandatanganan kode dari Otoritas Sertifikat untuk distribusi produksi.
  • Microsoft Store menandatangani MSIX untuk Anda, tidak perlu menandatangani sebelum pengiriman.
  • Anda mungkin memerlukan paket MSIX terpisah untuk setiap arsitektur yang Anda dukung (x64, Arm64).