Menggunakan CLI winapp dengan C++ dan CMake

Panduan ini menunjukkan cara menggunakan winapp CLI 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 Notifikasi, Keamanan, API AI, dll), memiliki pengalaman penginstalan/penghapusan instalasi yang 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 (atau memperbarui jika sudah diinstal):

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

    Reboot setelah penginstalan.

  2. CMake: Instal CMake (atau perbarui jika sudah diinstal):

    winget install Kitware.CMake --source winget
    
  3. winapp CLI: Instal winapp cli melalui winget (atau perbarui jika sudah diinstal):

    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

Seharusnya output adalah "Halo, dunia!"

2. Perbarui Kode untuk Memeriksa Identitas

Kami akan memperbarui aplikasi untuk memeriksa apakah aplikasi berjalan dengan identitas paket. Ini akan membantu kami memverifikasi bahwa identitas berfungsi dengan benar di langkah-langkah selanjutnya. Kita akan menggunakan API Windows Runtime C++ untuk mengakses API Paket.

Pertama, tambahkan baris berikut ke akhir CMakeLists.txt Anda untuk menautkan ke pustaka Windows App Model:

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

Selanjutnya, ganti seluruh konten main.cpp dengan kode berikut. Kode ini mencoba mengambil identitas paket saat ini menggunakan API Windows Runtime. Jika berhasil, nama keluarga paket akan dicetak; jika tidak, ia mencetak "Tidak dibungkus".

#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. Jalankan Tanpa Identitas

Sekarang, bangun kembali dan jalankan aplikasi seperti biasa:

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

Anda akan melihat output "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 dalam sekali jalan: manifes aplikasi, aset, dan secara opsional SDK Aplikasi Windows header untuk pengembangan C++.

Jalankan perintah berikut dan ikuti perintah:

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 SDK Aplikasi Windows dan menghasilkan header C++

Perintah ini akan:

  • Buat Package.appxmanifest — manifes yang menentukan identitas aplikasi Anda
  • Buat Assets folder — ikon yang diperlukan untuk pengemasan MSIX dan pengiriman Store
  • Buat folder .winapp dengan header dan pustaka SDK Aplikasi Windows
  • Membuat winapp.yaml file konfigurasi untuk menyematkan versi SDK

Anda dapat membuka Package.appxmanifest untuk menyesuaikan properti lebih lanjut seperti nama tampilan, penerbit, dan kemampuan.

Menambahkan Alias Eksekusi (untuk aplikasi konsol)

Alias eksekusi memungkinkan pengguna menjalankan aplikasi Anda berdasarkan nama dari terminal apa pun (seperti cpp-app). Ini juga memungkinkan winapp run --with-alias selama pengembangan, dengan menyimpan output konsol di terminal saat ini alih-alih membuka jendela baru.

Anda dapat menambahkannya secara otomatis:

winapp manifest add-alias

Atau secara manual: buka Package.appxmanifest dan tambahkan uap5 namespace ke <Package> tag jika hilang, lalu tambahkan ekstensi di dalamnya <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. Debugging dengan Identifikasi

Untuk menguji fitur yang memerlukan identitas (seperti Pemberitahuan) tanpa sepenuhnya mengemas aplikasi, Anda dapat menggunakan winapp run. Ini mendaftarkan paket tata letak tidak terikat (sama seperti penginstalan MSIX nyata) dan memulai aplikasi dalam satu langkah. Tidak diperlukan sertifikat atau penandatanganan untuk debug.

  1. Buat executable:

    cmake --build build --config Debug
    
  2. Jalankan dengan identitas:

    winapp run .\build\Debug --with-alias
    

Bendera --with-alias meluncurkan aplikasi melalui alias eksekusinya sehingga output konsol tetap berada di terminal saat ini. Ini memerlukan uap5:ExecutionAlias yang kami tambahkan di langkah 4.

Tip

winapp run juga mendaftarkan paket pada sistem Anda. Inilah sebabnya mengapa MSIX mungkin muncul sebagai "sudah diinstal" ketika Anda mencoba menginstalnya nanti di langkah 8. Gunakan winapp unregister untuk membersihkan paket pengembangan setelah selesai.

Anda sekarang akan melihat output yang mirip dengan:

Package Family Name: cpp-app_12345abcde

Ini mengonfirmasi bahwa aplikasi Anda berjalan dengan identitas paket yang valid!

Alternatif: Identitas paket jarang

Jika Anda memerlukan perilaku paket jarang secara khusus (identitas tanpa menyalin file), Anda dapat menggunakan create-debug-identity sebagai gantinya:

winapp create-debug-identity .\build\Debug\cpp-app.exe
.\build\Debug\cpp-app.exe

Tip

Untuk alur kerja penelusuran kesalahan tingkat lanjut (melampirkan debugger, penyiapan IDE, penelusuran kesalahan startup), lihat Panduan Penelusuran Kesalahan.

6. Menggunakan SDK Aplikasi Windows (Opsional)

Jika Anda memilih untuk menyiapkan SDK selama winapp init, Anda sekarang memiliki akses ke header SDK Aplikasi Windows di folder .winapp/include. Ini memberi Anda akses ke API Windows modern seperti pemberitahuan, windowing, AI di perangkat, dan banyak lagi. Jika Anda hanya memerlukan identitas paket untuk distribusi, Anda dapat melompat ke langkah 7.

Mari kita tambahkan contoh sederhana yang menampilkan versi Windows App Runtime.

Memperbarui CMakeLists.txt

Tambahkan baris berikut ke akhir CMakeLists.txt Anda untuk menyertakan header SDK Aplikasi Windows:

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

Memperbarui main.cpp

Ganti seluruh konten 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() {
    // 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;
}

Kompilasi dan Jalankan

Bangun ulang aplikasi dengan header SDK Aplikasi Windows:

cmake --build build --config Debug
winapp run .\build\Debug --with-alias

Anda sekarang akan melihat output seperti:

Package Family Name: cpp-app_12345abcde
Windows App Runtime Version: 1.8-stable (1.8.0)

Direktori .winapp/include berisi semua header yang diperlukan untuk SDK Aplikasi Windows, termasuk:

  • winrt/ - Header proyeksi WinRT C++ untuk akses ke API Windows Runtime
  • Microsoft.UI.*.h - Header WinUI 3 untuk komponen UI modern
  • MddBootstrap.h - Pemulaian SDK Aplikasi Windows
  • WindowsAppSDK-VersionInfo.h - Informasi versi
  • Dan banyak lagi komponen SDK Aplikasi Windows

Untuk penggunaan SDK Aplikasi Windows yang lebih canggih, lihat dokumentasi SDK Aplikasi Windows.

7. Pulihkan header saat diperlukan

Folder .winapp secara otomatis ditambahkan ke .gitignore oleh winapp init, sehingga tidak akan diperiksa ke kontrol sumber. Ketika orang lain mengkloning proyek Anda, mereka harus memulihkan file-file ini sebelum membangun.

Penyetelan Manual

Jalankan dua perintah ini setelah mengkloning repositori:

# 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

Kemudian Anda dapat membangun dan menjalankan secara normal dengan cmake -B build dan cmake --build build --config Debug.

Penyiapan Otomatis dengan CMake

Atau, Anda dapat mengotomasikan tugas ini dengan menambahkan logika pengaturan pada CMakeLists.txt. Berikut adalah versi penuh CMakeLists.txt dengan otomatisasi, penautan yang tepat, dan dengan standar minimal 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)

Dengan penyiapan ini:

  • Ketika seseorang mengkloning repositori dan menjalankan cmake -B build, winapp secara otomatis diunduh jika tidak ditemukan di PATH
  • Header dan sertifikat SDK Aplikasi Windows dipulihkan secara otomatis
  • Perintah hanya berjalan sekali selama konfigurasi (bukan pada setiap build) karena mereka memeriksa apakah file sudah ada
  • Jika perintah gagal, CMake menunjukkan peringatan dengan instruksi untuk menjalankannya secara manual
  • Winapp yang diunduh disimpan di .winapp-tools/ (tambahkan ini ke .gitignore jika diperlukan)

8. Paket dengan MSIX

Setelah siap mendistribusikan aplikasi, Anda dapat mengemasnya sebagai MSIX menggunakan manifes yang sama. MSIX menyediakan penginstalan/penghapusan instalasi yang bersih, pembaruan otomatis, dan pengalaman penginstalan tepercaya.

Menyiapkan Direktori Paket

Pertama, bangun aplikasi Anda dalam mode rilis untuk performa optimal:

cmake --build build --config Release

Kemudian, buat direktori hanya dengan file yang diperlukan untuk distribusi dan salin rilis Anda yang dapat dieksekusi:

mkdir dist
copy .\build\Release\cpp-app.exe .\dist\

Membuat Sertifikat Pengembangan

Paket MSIX harus ditandatangani. Untuk pengujian lokal, buat sertifikat pengembangan yang ditandatangani sendiri:

winapp cert generate --if-exists skip

Tip

Publisher sertifikat harus cocok dengan Publisher di Package.appxmanifest Anda. Perintah cert generate akan membaca ini secara otomatis dari manifes Anda.

Tanda tangani dan Kemas

Sekarang Anda dapat mengemas dan menandatangani:

# package and sign the app with the generated certificate
winapp pack .\dist --cert .\devcert.pfx 

Tip

Perintah pack secara otomatis menggunakan Package.appxmanifest dari direktori Anda saat ini dan menyalinnya ke folder target sebelum pengemasan. File yang dihasilkan .msix akan berada di direktori saat ini.

Menginstal Sertifikat

Sebelum Anda dapat menginstal paket MSIX, Anda perlu mempercayai sertifikat pengembangan pada komputer Anda. Jalankan perintah ini sebagai administrator (Anda hanya perlu melakukan ini sekali per sertifikat):

winapp cert install .\devcert.pfx

Instal dan Jalankan

Tip

Jika Anda menggunakan winapp run di langkah 5, paket mungkin sudah terdaftar di sistem Anda. Gunakan winapp unregister terlebih dahulu untuk menghapus pendaftaran pengembangan, lalu instal paket rilis.

Perintah winapp pack menghasilkan file MSIX di direktori akar proyek Anda. Instal paket dengan mengeklik dua kali file yang dihasilkan .msix , atau menggunakan PowerShell:

Add-AppxPackage .\cpp-app_1.0.0.0_x64.msix

Tip

Nama file MSIX mencakup versi dan arsitektur (misalnya, cpp-app_1.0.0.0_arm64.msix). Periksa direktori Anda untuk nama file yang tepat.

Sekarang Anda dapat menjalankan aplikasi dari mana saja di terminal dengan mengetik:

cpp-app

Anda seharusnya melihat output "Nama Keluarga Paket" yang mengonfirmasi bahwa itu diinstal dan berjalan dengan menggunakan identitas.

Tip

Jika Anda perlu mengemas ulang aplikasi Anda (misalnya, setelah perubahan kode), tambahkan Version di aplikasi Anda Package.appxmanifest sebelum berjalan winapp pack lagi. Windows memerlukan nomor versi yang lebih tinggi untuk memperbarui paket yang diinstal.

Tips

  1. Setelah siap untuk didistribusikan, Anda dapat menandatangani MSIX dengan sertifikat penandatanganan kode dari Otoritas Sertifikat sehingga pengguna Anda tidak perlu menginstal sertifikat yang ditandatangani sendiri.
  2. Layanan Penandatanganan Tepercaya Azure adalah cara yang bagus untuk mengelola sertifikat Anda dengan aman dan mengintegrasikan penandatanganan ke dalam alur CI/CD Anda.
  3. Microsoft Store akan menandatangani MSIX untuk Anda, tidak perlu menandatangani sebelum pengiriman.
  4. Anda mungkin perlu membuat beberapa paket MSIX, satu untuk setiap arsitektur yang Anda dukung (x64, Arm64). Konfigurasikan CMake dengan bendera generator dan arsitektur yang sesuai.

Langkah Selanjutnya