From 84afff44c303b7355a85b272b0cc533b83dfe53a Mon Sep 17 00:00:00 2001 From: ssparach <128866445+ssparach@users.noreply.github.com> Date: Tue, 19 May 2026 12:11:12 -0700 Subject: [PATCH] metapackage samples and refinements in consumption model --- Samples/CMake/CMakeLists.txt | 44 +-- Samples/CMake/Metapackage/CMakeLists.txt | 74 +++++ Samples/CMake/Metapackage/CMakePresets.json | 36 +++ .../PackagedFrameworkDependent/CMakeLists.txt | 40 +++ .../PackagedFrameworkDependent/Logo.png | Bin 0 -> 69 bytes .../PackagedFrameworkDependent/main.cpp | 280 ++++++++++++++++ .../PackagedSelfContained/CMakeLists.txt | 40 +++ .../PackagedSelfContained/Logo.png | Bin 0 -> 69 bytes .../PackagedSelfContained/main.cpp | 280 ++++++++++++++++ .../CMakeLists.txt | 27 ++ .../UnpackagedFrameworkDependent/main.cpp | 301 ++++++++++++++++++ .../UnpackagedSelfContained/CMakeLists.txt | 27 ++ .../UnpackagedSelfContained/main.cpp | 280 ++++++++++++++++ .../PackagedFrameworkDependent/CMakeLists.txt | 19 +- .../CMake/PackagedFrameworkDependent/main.cpp | 4 +- .../PackagedSelfContained/CMakeLists.txt | 21 +- Samples/CMake/PackagedSelfContained/main.cpp | 2 +- .../CMakeLists.txt | 20 +- .../UnpackagedFrameworkDependent/main.cpp | 2 +- .../UnpackagedSelfContained/CMakeLists.txt | 24 +- .../CMake/UnpackagedSelfContained/main.cpp | 2 +- 21 files changed, 1447 insertions(+), 76 deletions(-) create mode 100644 Samples/CMake/Metapackage/CMakeLists.txt create mode 100644 Samples/CMake/Metapackage/CMakePresets.json create mode 100644 Samples/CMake/Metapackage/PackagedFrameworkDependent/CMakeLists.txt create mode 100644 Samples/CMake/Metapackage/PackagedFrameworkDependent/Logo.png create mode 100644 Samples/CMake/Metapackage/PackagedFrameworkDependent/main.cpp create mode 100644 Samples/CMake/Metapackage/PackagedSelfContained/CMakeLists.txt create mode 100644 Samples/CMake/Metapackage/PackagedSelfContained/Logo.png create mode 100644 Samples/CMake/Metapackage/PackagedSelfContained/main.cpp create mode 100644 Samples/CMake/Metapackage/UnpackagedFrameworkDependent/CMakeLists.txt create mode 100644 Samples/CMake/Metapackage/UnpackagedFrameworkDependent/main.cpp create mode 100644 Samples/CMake/Metapackage/UnpackagedSelfContained/CMakeLists.txt create mode 100644 Samples/CMake/Metapackage/UnpackagedSelfContained/main.cpp diff --git a/Samples/CMake/CMakeLists.txt b/Samples/CMake/CMakeLists.txt index 0d953d6bf..daae3da5d 100644 --- a/Samples/CMake/CMakeLists.txt +++ b/Samples/CMake/CMakeLists.txt @@ -28,6 +28,13 @@ FetchContent_Declare( FetchContent_MakeAvailable(NuGetCMakePackage) +#---------------------------------------------------------------------------------------------------------------------- +# These samples illustrate individual component usage — picking and choosing between the +# NuGet packages shipped as part of the WindowsAppSDK. If you want the entirety of the +# WindowsAppSDK pulled in via a single dependency, see the Metapackage sample for a +# better illustration of that use case. +#---------------------------------------------------------------------------------------------------------------------- + add_nuget_packages( CONFIG_FILE ${CMAKE_SOURCE_DIR}/nuget.config LOCK_FILE ${CMAKE_SOURCE_DIR}/packages.lock.json @@ -42,12 +49,13 @@ add_nuget_packages( Microsoft.WindowsAppSDK.Widgets 2.0.4-experimental Microsoft.WindowsAppSDK.AI 2.0.179-experimental Microsoft.WindowsAppSDK.ML 2.0.325-experimental - Microsoft.Web.WebView2 1.0.3719.77 Microsoft.WindowsAppSDK.WinUI 2.0.10-experimental ) find_package(Microsoft.WindowsAppSDK.Base CONFIG REQUIRED) +find_package(Microsoft.WindowsAppSDK.Runtime CONFIG REQUIRED) find_package(Microsoft.WindowsAppSDK.Foundation CONFIG REQUIRED) +find_package(Microsoft.WindowsAppSDK.InteractiveExperiences CONFIG REQUIRED) find_package(Microsoft.WindowsAppSDK.DWrite CONFIG REQUIRED) find_package(Microsoft.WindowsAppSDK.Widgets CONFIG REQUIRED) find_package(Microsoft.WindowsAppSDK.AI CONFIG REQUIRED) @@ -58,38 +66,8 @@ find_package(Microsoft.WindowsAppSDK.WinUI CONFIG REQUIRED) include(${CMAKE_SOURCE_DIR}/Configuration.cmake) link_libraries(Configuration) -# Macro to copy runtime DLLs to the output directory -macro(post_build_runtime_dll_copy target_name) - if(WIN32) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND "${CMAKE_COMMAND};-E;$>,copy;$;$,true>" - COMMAND_EXPAND_LISTS - ) - endif() -endmacro() - -# For pure WinRT components (Widgets, AI, WinUI) that have no import libraries (.lib). -# These components store DLL paths in a custom INTERFACE_SELFCONTAINED_RUNTIME_DLLS property instead. This macro -# reads that property and copies the DLLs via post-build commands. -macro(post_build_selfcontained_dll_copy target_name) - foreach(_sc_target - Microsoft.WindowsAppSDK.Widgets_SelfContained - Microsoft.WindowsAppSDK.AI_SelfContained - Microsoft.WindowsAppSDK.ML_SelfContained - Microsoft.WindowsAppSDK.WinUI_SelfContained - ) - if(TARGET ${_sc_target}) - get_property(_sc_dlls TARGET ${_sc_target} PROPERTY INTERFACE_SELFCONTAINED_RUNTIME_DLLS) - if(_sc_dlls) - foreach(_dll IN LISTS _sc_dlls) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_dll}" "$" - ) - endforeach() - endif() - endif() - endforeach() -endmacro() +# Post-build helpers are provided by +# Microsoft.WindowsAppSDK.Base via WindowsAppSDKHelpers.cmake. # Subdirectories add_subdirectory(UnpackagedSelfContained) diff --git a/Samples/CMake/Metapackage/CMakeLists.txt b/Samples/CMake/Metapackage/CMakeLists.txt new file mode 100644 index 000000000..fb3e944d2 --- /dev/null +++ b/Samples/CMake/Metapackage/CMakeLists.txt @@ -0,0 +1,74 @@ +#---------------------------------------------------------------------------------------------------------------------- +# Metapackage samples — shared root +# +# Demonstrates the new umbrella consumption shape for Microsoft.WindowsAppSDK across the four +# deployment-matrix combinations (Packaged/Unpackaged × Framework-dep/Self-contained): +# +# - Single add_nuget_packages() entry for the metapackage. Every component the metapackage +# transitively pulls in is automatically materialized. +# - Single find_package(Microsoft.WindowsAppSDK CONFIG REQUIRED). The umbrella config +# materializes every component. +# - Each sample subdirectory is thin: project + add_executable + per-target properties +# (WindowsPackageType, WindowsAppSDKSelfContained, auto-init switches) + single +# target_link_libraries(... Microsoft.WindowsAppSDK). +# - No per-component find_package or per-target *_Framework / *_SelfContained suffix linking. +#---------------------------------------------------------------------------------------------------------------------- +cmake_minimum_required(VERSION 3.31) + +cmake_policy(SET CMP0141 NEW) +cmake_policy(SET CMP0117 NEW) + +if(CMAKE_GENERATOR MATCHES "^Visual Studio") + file(WRITE "${CMAKE_BINARY_DIR}/Directory.Build.rsp" "-m -graphBuild:true -p:UseMultiToolTask=true -nodeReuse:false -terminalLogger:auto") + file(WRITE "${CMAKE_BINARY_DIR}/Directory.Build.props" "") + file(WRITE "${CMAKE_BINARY_DIR}/Directory.Build.targets" "") +elseif(CMAKE_GENERATOR MATCHES "^Ninja") + if(NOT (DEFINED ENV{Platform})) + message(FATAL_ERROR "When using the Ninja generator, you must build from a platform-specific Developer Command Prompt.") + endif() +endif() + +project(MetapackageSamples LANGUAGES CXX) + +include(FetchContent) + +FetchContent_Declare( + NuGetCMakePackage + GIT_REPOSITORY https://github.com/mschofie/NuGetCMakePackage + GIT_TAG develop +) + +FetchContent_MakeAvailable(NuGetCMakePackage) + +add_nuget_packages( + CONFIG_FILE ${CMAKE_SOURCE_DIR}/../nuget.config + LOCK_FILE ${CMAKE_SOURCE_DIR}/packages.lock.json + FRAMEWORK native + PACKAGES + Microsoft.Windows.CppWinRT 2.0.251203.1 + Microsoft.WindowsAppSDK 2.0.0-experimental7 +) + +# Single find_package — the metapackage's umbrella config materializes every component. +find_package(Microsoft.WindowsAppSDK CONFIG REQUIRED) + +# Common compiler configuration +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +add_compile_definitions(NOMINMAX WIN32_LEAN_AND_MEAN UNICODE _UNICODE) + +#---------------------------------------------------------------------------------------------------------------------- +# Post-build helpers +# +# wasdk_post_build_copy() and friends are provided by Microsoft.WindowsAppSDK.Base via +# WindowsAppSDKHelpers.cmake. Loaded transitively by every component find_package call, +# so consumer CMakeLists files do not need to define any post-build plumbing themselves. +#---------------------------------------------------------------------------------------------------------------------- + +#---------------------------------------------------------------------------------------------------------------------- +# Sub-samples (one per deployment matrix cell) +#---------------------------------------------------------------------------------------------------------------------- +add_subdirectory(PackagedFrameworkDependent) +add_subdirectory(PackagedSelfContained) +add_subdirectory(UnpackagedFrameworkDependent) +add_subdirectory(UnpackagedSelfContained) diff --git a/Samples/CMake/Metapackage/CMakePresets.json b/Samples/CMake/Metapackage/CMakePresets.json new file mode 100644 index 000000000..1920de98f --- /dev/null +++ b/Samples/CMake/Metapackage/CMakePresets.json @@ -0,0 +1,36 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 31, + "patch": 0 + }, + "configurePresets": [ + { + "name": "vs2022-x64", + "displayName": "Visual Studio 2022 x64", + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "binaryDir": "D:/b/meta-vs64", + "cacheVariables": { + "FETCHCONTENT_SOURCE_DIR_NUGETCMAKEPACKAGE": "D:/UndockedProjects/NugetCMakePackage" + } + }, + { + "name": "ninja-x64", + "displayName": "Ninja Multi-Config x64", + "generator": "Ninja Multi-Config", + "binaryDir": "D:/b/meta-nx64", + "cacheVariables": { + "CMAKE_OBJECT_PATH_MAX": "1000", + "FETCHCONTENT_SOURCE_DIR_NUGETCMAKEPACKAGE": "D:/UndockedProjects/NugetCMakePackage" + } + } + ], + "buildPresets": [ + { "name": "vs2022-x64-debug", "configurePreset": "vs2022-x64", "configuration": "Debug" }, + { "name": "vs2022-x64-release", "configurePreset": "vs2022-x64", "configuration": "Release" }, + { "name": "ninja-x64-debug", "configurePreset": "ninja-x64", "configuration": "Debug" }, + { "name": "ninja-x64-release", "configurePreset": "ninja-x64", "configuration": "Release" } + ] +} diff --git a/Samples/CMake/Metapackage/PackagedFrameworkDependent/CMakeLists.txt b/Samples/CMake/Metapackage/PackagedFrameworkDependent/CMakeLists.txt new file mode 100644 index 000000000..56acdc374 --- /dev/null +++ b/Samples/CMake/Metapackage/PackagedFrameworkDependent/CMakeLists.txt @@ -0,0 +1,40 @@ +#---------------------------------------------------------------------------------------------------------------------- +# Metapackage_PackagedFrameworkDependent +# Packaged + Framework-dependent. Default mode (no WindowsAppSDKSelfContained property set). +#---------------------------------------------------------------------------------------------------------------------- +project(Metapackage_PackagedFrameworkDependent LANGUAGES CXX) + +add_executable(Metapackage_PackagedFrameworkDependent WIN32 + main.cpp +) + +set_target_properties(Metapackage_PackagedFrameworkDependent PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL" + # Packaged FW: WindowsPackageType defaults to MSIX → DeploymentManager auto-init enabled by default. + WindowsAppSdkDeploymentManagerInitialize TRUE + # WindowsAppSDKSelfContained unset (default FALSE) → basic component targets resolve to _Framework. +) + +# Single link entry — basic component targets inside the umbrella resolve to _Framework. +target_link_libraries(Metapackage_PackagedFrameworkDependent + PRIVATE + Microsoft.WindowsAppSDK +) + +wasdk_post_build_copy(Metapackage_PackagedFrameworkDependent) + +# Generate AppxManifest.xml with framework PackageDependency auto-injected. +wasdk_generate_appx_manifest( + TARGET Metapackage_PackagedFrameworkDependent + IDENTITY_NAME "CMake-Metapackage-PackagedFrameworkDependent" + IDENTITY_PUBLISHER "CN=TestPublisher" + IDENTITY_VERSION "1.0.0.0" + DISPLAY_NAME "Metapackage Packaged FW (CMake)" + DESCRIPTION "Packaged framework-dependent CMake test using metapackage umbrella" +) + +add_custom_command(TARGET Metapackage_PackagedFrameworkDependent POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Logo.png + $ +) diff --git a/Samples/CMake/Metapackage/PackagedFrameworkDependent/Logo.png b/Samples/CMake/Metapackage/PackagedFrameworkDependent/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5e12fa82813cafe79981b23b299a3f50bdf1d288 GIT binary patch literal 69 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2ryJf1F&Asp9}f1E!6 +#include +#include +#include + +// WinRT base +#include + +// Foundation - EnvironmentManager, PowerManager +#include +#include + +// DWrite - DWriteCore text rendering engine +#include + +// IXP (InteractiveExperiences) - AppWindowTitleBar customization support +#include + +// Widgets - WidgetManager provider API +#include + +// AI - LanguageModel readiness check +#include +#include + +// ML - Windows ML ExecutionProvider catalog +#include + +// WinUI - XAML CornerRadiusHelper +#pragma push_macro("GetCurrentTime") +#undef GetCurrentTime +#include +#pragma pop_macro("GetCurrentTime") + +int WINAPI wWinMain( + _In_ HINSTANCE, + _In_opt_ HINSTANCE, + _In_ PWSTR, + _In_ int) +{ + wchar_t tempPath[MAX_PATH]{}; + GetTempPathW(MAX_PATH, tempPath); + std::wstring logPath = std::wstring(tempPath) + L"CMake_PackagedFW.log"; + std::wofstream log(logPath, std::ios::trunc); + + try + { + winrt::init_apartment(winrt::apartment_type::single_threaded); + + std::wostringstream message; + message << L"Metapackage Sample: Packaged Framework Dependent App (CMake)\n\n"; + + //-------------------------------------------------------------------------------------------------------------- + // Foundation + //-------------------------------------------------------------------------------------------------------------- + message << L"[Foundation]\n"; + + if (winrt::Microsoft::Windows::System::EnvironmentManager::IsSupported()) + { + auto envManager = winrt::Microsoft::Windows::System::EnvironmentManager::GetForProcess(); + auto value = envManager.GetEnvironmentVariable(L"PROCESSOR_ARCHITECTURE"); + message << L" EnvironmentManager: Supported\n" + << L" PROCESSOR_ARCHITECTURE: " << std::wstring(value) << L"\n"; + log << L"Foundation=Supported" << std::endl; + } + else + { + message << L" EnvironmentManager: Not supported\n"; + log << L"Foundation=NotSupported" << std::endl; + } + + namespace Power = winrt::Microsoft::Windows::System::Power; + + auto batteryStatus = Power::PowerManager::BatteryStatus(); + message << L" BatteryStatus: "; + switch (batteryStatus) + { + case Power::BatteryStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::BatteryStatus::Discharging: + message << L"Discharging"; + break; + case Power::BatteryStatus::Idle: + message << L"Idle"; + break; + case Power::BatteryStatus::Charging: + message << L"Charging"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + auto powerSupply = Power::PowerManager::PowerSupplyStatus(); + message << L" PowerSupplyStatus: "; + switch (powerSupply) + { + case Power::PowerSupplyStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::PowerSupplyStatus::Inadequate: + message << L"Inadequate"; + break; + case Power::PowerSupplyStatus::Adequate: + message << L"Adequate"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + message << L" RemainingChargePercent: " << Power::PowerManager::RemainingChargePercent() << L"%\n"; + + //-------------------------------------------------------------------------------------------------------------- + // DWrite + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[DWrite]\n"; + + winrt::com_ptr dwriteFactory; + HRESULT hr = DWriteCoreCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(dwriteFactory.put()) + ); + message << L" DWriteCoreCreateFactory: " << (SUCCEEDED(hr) ? L"Loaded" : L"Failed") << L"\n"; + log << (SUCCEEDED(hr) ? L"DWrite=Loaded" : L"DWrite=Failed") << std::endl; + + //-------------------------------------------------------------------------------------------------------------- + // IXP (InteractiveExperiences) + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[InteractiveExperiences]\n"; + + try + { + bool isSupported = winrt::Microsoft::UI::Windowing::AppWindowTitleBar::IsCustomizationSupported(); + message << L" AppWindowTitleBar.IsCustomizationSupported: " << (isSupported ? L"true" : L"false") << L"\n"; + log << (isSupported ? L"IXP=true" : L"IXP=false") << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" AppWindowTitleBar.IsCustomizationSupported: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"IXP=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // Widgets + // NOTE: WidgetManager requires MSIX package identity AND the WinAppSDK Framework package. + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[Widgets]\n"; + + try + { + auto widgetManager = winrt::Microsoft::Windows::Widgets::Providers::WidgetManager::GetDefault(); + auto widgets = widgetManager.GetWidgetInfos(); + message << L" WidgetManager.GetWidgetInfos: count = " << widgets.size() << L"\n"; + log << L"Widgets=count_" << widgets.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" WidgetManager.GetDefault: 0x" << std::hex << ex.code() << std::dec + << L" (requires package identity and framework-dependent deployment)\n"; + log << L"Widgets=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // AI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[AI]\n"; + + try + { + auto readyState = winrt::Microsoft::Windows::AI::Text::LanguageModel::GetReadyState(); + std::wstring stateStr; + switch (readyState) + { + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::Ready: + stateStr = L"Ready"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotReady: + stateStr = L"NotReady"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotSupportedOnCurrentSystem: + stateStr = L"NotSupportedOnCurrentSystem"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::DisabledByUser: + stateStr = L"DisabledByUser"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::CapabilityMissing: + stateStr = L"CapabilityMissing"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotCompatibleWithSystemHardware: + stateStr = L"NotCompatibleWithSystemHardware"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::OSUpdateNeeded: + stateStr = L"OSUpdateNeeded"; + break; + default: + stateStr = std::to_wstring(static_cast(readyState)); + break; + } + message << L" LanguageModel.GetReadyState: " << stateStr << L"\n"; + log << L"AI=" << stateStr << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" LanguageModel.GetReadyState: 0x" << std::hex << ex.code() << std::dec + << L" (expected on non-AI hardware)\n"; + log << L"AI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // ML + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[ML]\n"; + + try + { + auto catalog = winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog::GetDefault(); + auto providers = catalog.FindAllProviders(); + message << L" ExecutionProviderCatalog.FindAllProviders: count = " << providers.size() << L"\n"; + log << L"ML=providers_" << providers.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" ExecutionProviderCatalog: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"ML=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // WinUI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[WinUI]\n"; + + try + { + auto cornerRadius = winrt::Microsoft::UI::Xaml::CornerRadiusHelper::FromUniformRadius(4.0); + message << L" CornerRadiusHelper.FromUniformRadius(4.0): TopLeft=" + << cornerRadius.TopLeft << L" BottomRight=" << cornerRadius.BottomRight << L"\n"; + log << L"WinUI=TopLeft_" << cornerRadius.TopLeft + << L"_BottomRight_" << cornerRadius.BottomRight << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" CornerRadiusHelper: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"WinUI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + log << L"Result=SUCCESS" << std::endl; + log.close(); + + MessageBoxW( + nullptr, + message.str().c_str(), + L"WinAppSDK CMake Smoke Test", + MB_OK | MB_ICONINFORMATION + ); + } + catch (winrt::hresult_error const& ex) + { + log << L"Error=0x" << std::hex << static_cast(ex.code()) << std::endl; + log.close(); + std::wostringstream err; + err << L"WinRT error 0x" << std::hex << ex.code() << L"\n" << ex.message().c_str(); + MessageBoxW( + nullptr, + err.str().c_str(), + L"WinAppSDK Error", + MB_OK | MB_ICONERROR + ); + return 1; + } + + return 0; +} diff --git a/Samples/CMake/Metapackage/PackagedSelfContained/CMakeLists.txt b/Samples/CMake/Metapackage/PackagedSelfContained/CMakeLists.txt new file mode 100644 index 000000000..71c1f4460 --- /dev/null +++ b/Samples/CMake/Metapackage/PackagedSelfContained/CMakeLists.txt @@ -0,0 +1,40 @@ +#---------------------------------------------------------------------------------------------------------------------- +# Metapackage_PackagedSelfContained +# Packaged + Self-contained. WindowsAppSDKSelfContained=TRUE. +#---------------------------------------------------------------------------------------------------------------------- +project(Metapackage_PackagedSelfContained LANGUAGES CXX) + +add_executable(Metapackage_PackagedSelfContained WIN32 + main.cpp +) + +set_target_properties(Metapackage_PackagedSelfContained PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL" + # One property — every basic component target resolves to _SelfContained. + WindowsAppSDKSelfContained TRUE +) + +# Single link entry — bare component targets inside the umbrella resolve to _SelfContained. +target_link_libraries(Metapackage_PackagedSelfContained + PRIVATE + Microsoft.WindowsAppSDK +) + +wasdk_post_build_copy(Metapackage_PackagedSelfContained) + +# Generate AppxManifest.xml. Self-contained apps still benefit from a packaged manifest for MSIX +# distribution. The helper can be used here as well or you can provide your own manifest if you need to customize it beyond what the helper supports for the package self contained scenario. +wasdk_generate_appx_manifest( + TARGET Metapackage_PackagedSelfContained + IDENTITY_NAME "CMake-Metapackage-PackagedSelfContained" + IDENTITY_PUBLISHER "CN=TestPublisher" + IDENTITY_VERSION "1.0.0.0" + DISPLAY_NAME "Metapackage Packaged SC (CMake)" + DESCRIPTION "Packaged self-contained CMake test using metapackage umbrella" +) + +add_custom_command(TARGET Metapackage_PackagedSelfContained POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/Logo.png + $ +) diff --git a/Samples/CMake/Metapackage/PackagedSelfContained/Logo.png b/Samples/CMake/Metapackage/PackagedSelfContained/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5e12fa82813cafe79981b23b299a3f50bdf1d288 GIT binary patch literal 69 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2ryJf1F&Asp9}f1E!6 +#include +#include +#include + +// WinRT base +#include + +// Foundation - EnvironmentManager, PowerManager +#include +#include + +// DWrite - DWriteCore text rendering engine +#include + +// IXP (InteractiveExperiences) - AppWindowTitleBar customization support +#include + +// Widgets - WidgetManager provider API +#include + +// AI - LanguageModel readiness check +#include +#include + +// ML - Windows ML ExecutionProvider catalog +#include + +// WinUI - XAML CornerRadiusHelper +#pragma push_macro("GetCurrentTime") +#undef GetCurrentTime +#include +#pragma pop_macro("GetCurrentTime") + +int WINAPI wWinMain( + _In_ HINSTANCE, + _In_opt_ HINSTANCE, + _In_ PWSTR, + _In_ int) +{ + wchar_t tempPath[MAX_PATH]{}; + GetTempPathW(MAX_PATH, tempPath); + std::wstring logPath = std::wstring(tempPath) + L"CMake_PackagedSC.log"; + std::wofstream log(logPath, std::ios::trunc); + + try + { + winrt::init_apartment(winrt::apartment_type::single_threaded); + + std::wostringstream message; + message << L"Metapackage Sample: Packaged Self-Contained App (CMake)\n\n"; + + //-------------------------------------------------------------------------------------------------------------- + // Foundation + //-------------------------------------------------------------------------------------------------------------- + message << L"[Foundation]\n"; + + if (winrt::Microsoft::Windows::System::EnvironmentManager::IsSupported()) + { + auto envManager = winrt::Microsoft::Windows::System::EnvironmentManager::GetForProcess(); + auto value = envManager.GetEnvironmentVariable(L"PROCESSOR_ARCHITECTURE"); + message << L" EnvironmentManager: Supported\n" + << L" PROCESSOR_ARCHITECTURE: " << std::wstring(value) << L"\n"; + log << L"Foundation=Supported" << std::endl; + } + else + { + message << L" EnvironmentManager: Not supported\n"; + log << L"Foundation=NotSupported" << std::endl; + } + + namespace Power = winrt::Microsoft::Windows::System::Power; + + auto batteryStatus = Power::PowerManager::BatteryStatus(); + message << L" BatteryStatus: "; + switch (batteryStatus) + { + case Power::BatteryStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::BatteryStatus::Discharging: + message << L"Discharging"; + break; + case Power::BatteryStatus::Idle: + message << L"Idle"; + break; + case Power::BatteryStatus::Charging: + message << L"Charging"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + auto powerSupply = Power::PowerManager::PowerSupplyStatus(); + message << L" PowerSupplyStatus: "; + switch (powerSupply) + { + case Power::PowerSupplyStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::PowerSupplyStatus::Inadequate: + message << L"Inadequate"; + break; + case Power::PowerSupplyStatus::Adequate: + message << L"Adequate"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + message << L" RemainingChargePercent: " << Power::PowerManager::RemainingChargePercent() << L"%\n"; + + //-------------------------------------------------------------------------------------------------------------- + // DWrite + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[DWrite]\n"; + + winrt::com_ptr dwriteFactory; + HRESULT hr = DWriteCoreCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(dwriteFactory.put()) + ); + message << L" DWriteCoreCreateFactory: " << (SUCCEEDED(hr) ? L"Loaded" : L"Failed") << L"\n"; + log << (SUCCEEDED(hr) ? L"DWrite=Loaded" : L"DWrite=Failed") << std::endl; + + //-------------------------------------------------------------------------------------------------------------- + // IXP (InteractiveExperiences) + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[InteractiveExperiences]\n"; + + try + { + bool isSupported = winrt::Microsoft::UI::Windowing::AppWindowTitleBar::IsCustomizationSupported(); + message << L" AppWindowTitleBar.IsCustomizationSupported: " << (isSupported ? L"true" : L"false") << L"\n"; + log << (isSupported ? L"IXP=true" : L"IXP=false") << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" AppWindowTitleBar.IsCustomizationSupported: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"IXP=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // Widgets + // NOTE: WidgetManager requires MSIX package identity AND the WinAppSDK Framework package. + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[Widgets]\n"; + + try + { + auto widgetManager = winrt::Microsoft::Windows::Widgets::Providers::WidgetManager::GetDefault(); + auto widgets = widgetManager.GetWidgetInfos(); + message << L" WidgetManager.GetWidgetInfos: count = " << widgets.size() << L"\n"; + log << L"Widgets=count_" << widgets.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" WidgetManager.GetDefault: 0x" << std::hex << ex.code() << std::dec + << L" (requires package identity and framework-dependent deployment)\n"; + log << L"Widgets=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // AI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[AI]\n"; + + try + { + auto readyState = winrt::Microsoft::Windows::AI::Text::LanguageModel::GetReadyState(); + std::wstring stateStr; + switch (readyState) + { + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::Ready: + stateStr = L"Ready"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotReady: + stateStr = L"NotReady"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotSupportedOnCurrentSystem: + stateStr = L"NotSupportedOnCurrentSystem"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::DisabledByUser: + stateStr = L"DisabledByUser"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::CapabilityMissing: + stateStr = L"CapabilityMissing"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotCompatibleWithSystemHardware: + stateStr = L"NotCompatibleWithSystemHardware"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::OSUpdateNeeded: + stateStr = L"OSUpdateNeeded"; + break; + default: + stateStr = std::to_wstring(static_cast(readyState)); + break; + } + message << L" LanguageModel.GetReadyState: " << stateStr << L"\n"; + log << L"AI=" << stateStr << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" LanguageModel.GetReadyState: 0x" << std::hex << ex.code() << std::dec + << L" (expected on non-AI hardware)\n"; + log << L"AI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // ML + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[ML]\n"; + + try + { + auto catalog = winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog::GetDefault(); + auto providers = catalog.FindAllProviders(); + message << L" ExecutionProviderCatalog.FindAllProviders: count = " << providers.size() << L"\n"; + log << L"ML=providers_" << providers.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" ExecutionProviderCatalog: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"ML=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // WinUI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[WinUI]\n"; + + try + { + auto cornerRadius = winrt::Microsoft::UI::Xaml::CornerRadiusHelper::FromUniformRadius(4.0); + message << L" CornerRadiusHelper.FromUniformRadius(4.0): TopLeft=" + << cornerRadius.TopLeft << L" BottomRight=" << cornerRadius.BottomRight << L"\n"; + log << L"WinUI=TopLeft_" << cornerRadius.TopLeft + << L"_BottomRight_" << cornerRadius.BottomRight << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" CornerRadiusHelper: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"WinUI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + log << L"Result=SUCCESS" << std::endl; + log.close(); + + MessageBoxW( + nullptr, + message.str().c_str(), + L"WinAppSDK CMake Smoke Test", + MB_OK | MB_ICONINFORMATION + ); + } + catch (winrt::hresult_error const& ex) + { + log << L"Error=0x" << std::hex << static_cast(ex.code()) << std::endl; + log.close(); + std::wostringstream err; + err << L"WinRT error 0x" << std::hex << ex.code() << L"\n" << ex.message().c_str(); + MessageBoxW( + nullptr, + err.str().c_str(), + L"WinAppSDK Error", + MB_OK | MB_ICONERROR + ); + return 1; + } + + return 0; +} diff --git a/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/CMakeLists.txt b/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/CMakeLists.txt new file mode 100644 index 000000000..fd2f2b93b --- /dev/null +++ b/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/CMakeLists.txt @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------------------------------------------------- +# Metapackage_UnpackagedFrameworkDependent +# Unpackaged + Framework-dependent. WindowsPackageType=None → Bootstrap auto-init enabled by default. +#---------------------------------------------------------------------------------------------------------------------- +project(Metapackage_UnpackagedFrameworkDependent LANGUAGES CXX) + +add_executable(Metapackage_UnpackagedFrameworkDependent WIN32 + main.cpp +) + +set_target_properties(Metapackage_UnpackagedFrameworkDependent PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL" + # Unpackaged: no MSIX. Bootstrap auto-init is enabled by default when WindowsPackageType=None. + WindowsPackageType "None" + WindowsAppSdkBootstrapInitialize TRUE + # WindowsAppSDKSelfContained unset (default FALSE) → basic component targets resolve to _Framework. +) + +# Single link entry — basic component targets inside the umbrella resolve to _Framework. +target_link_libraries(Metapackage_UnpackagedFrameworkDependent + PRIVATE + Microsoft.WindowsAppSDK +) + +wasdk_post_build_copy(Metapackage_UnpackagedFrameworkDependent) + +# No wasdk_generate_appx_manifest() — this is an unpackaged exe. diff --git a/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/main.cpp b/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/main.cpp new file mode 100644 index 000000000..87a02ecaf --- /dev/null +++ b/Samples/CMake/Metapackage/UnpackagedFrameworkDependent/main.cpp @@ -0,0 +1,301 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include +#include +#include +#include + +// WinRT base +#include + +// Foundation - EnvironmentManager, PowerManager +#include +#include + +// DWrite - DWriteCore text rendering engine +#include + +// IXP (InteractiveExperiences) - AppWindowTitleBar customization support +#include + +// Widgets - WidgetManager provider API +#include + +// AI - LanguageModel readiness check +#include +#include + +// ML - Windows ML ExecutionProvider catalog +#include + +// WinUI - XAML CornerRadiusHelper +#pragma push_macro("GetCurrentTime") +#undef GetCurrentTime +#include +#pragma pop_macro("GetCurrentTime") + +int WINAPI wWinMain( + _In_ HINSTANCE, + _In_opt_ HINSTANCE, + _In_ PWSTR, + _In_ int) +{ + wchar_t tempPath[MAX_PATH]{}; + GetTempPathW(MAX_PATH, tempPath); + std::wstring logPath = std::wstring(tempPath) + L"CMake_UnpackagedFW.log"; + std::wofstream log(logPath, std::ios::trunc); + + try + { + winrt::init_apartment(winrt::apartment_type::single_threaded); + + std::wostringstream message; + message << L"Metapackage Sample: Unpackaged Framework Dependent App (CMake)\n\n"; + + //-------------------------------------------------------------------------------------------------------------- + // Foundation + //-------------------------------------------------------------------------------------------------------------- + message << L"[Foundation]\n"; + + if (winrt::Microsoft::Windows::System::EnvironmentManager::IsSupported()) + { + auto envManager = winrt::Microsoft::Windows::System::EnvironmentManager::GetForProcess(); + auto value = envManager.GetEnvironmentVariable(L"PROCESSOR_ARCHITECTURE"); + message << L" EnvironmentManager: Supported\n" + << L" PROCESSOR_ARCHITECTURE: " << std::wstring(value) << L"\n"; + log << L"Foundation=Supported" << std::endl; + } + else + { + message << L" EnvironmentManager: Not supported\n"; + log << L"Foundation=NotSupported" << std::endl; + } + + namespace Power = winrt::Microsoft::Windows::System::Power; + + auto batteryStatus = Power::PowerManager::BatteryStatus(); + message << L" BatteryStatus: "; + switch (batteryStatus) + { + case Power::BatteryStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::BatteryStatus::Discharging: + message << L"Discharging"; + break; + case Power::BatteryStatus::Idle: + message << L"Idle"; + break; + case Power::BatteryStatus::Charging: + message << L"Charging"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + auto powerSupply = Power::PowerManager::PowerSupplyStatus(); + message << L" PowerSupplyStatus: "; + switch (powerSupply) + { + case Power::PowerSupplyStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::PowerSupplyStatus::Inadequate: + message << L"Inadequate"; + break; + case Power::PowerSupplyStatus::Adequate: + message << L"Adequate"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + message << L" RemainingChargePercent: " << Power::PowerManager::RemainingChargePercent() << L"%\n"; + + //-------------------------------------------------------------------------------------------------------------- + // DWrite + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[DWrite]\n"; + + auto dwriteModule = LoadLibraryW(L"DWriteCore.dll"); + if (dwriteModule) + { + using DWriteCoreCreateFactoryFn = HRESULT(WINAPI*)(DWRITE_FACTORY_TYPE, REFIID, IUnknown**); + auto createFactory = reinterpret_cast( + GetProcAddress(dwriteModule, "DWriteCoreCreateFactory") + ); + if (createFactory) + { + winrt::com_ptr dwriteFactory; + HRESULT hr = createFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(dwriteFactory.put()) + ); + message << L" DWriteCoreCreateFactory: " << (SUCCEEDED(hr) ? L"Loaded" : L"Failed") << L"\n"; + log << (SUCCEEDED(hr) ? L"DWrite=Loaded" : L"DWrite=Failed") << std::endl; + } + else + { + message << L" DWriteCore: DLL loaded but export not found\n"; + log << L"DWrite=Failed" << std::endl; + } + } + else + { + message << L" DWriteCore: Not available (install WinAppSDK runtime)\n"; + log << L"DWrite=Failed" << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // IXP (InteractiveExperiences) + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[InteractiveExperiences]\n"; + + try + { + bool isSupported = winrt::Microsoft::UI::Windowing::AppWindowTitleBar::IsCustomizationSupported(); + message << L" AppWindowTitleBar.IsCustomizationSupported: " << (isSupported ? L"true" : L"false") << L"\n"; + log << (isSupported ? L"IXP=true" : L"IXP=false") << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" AppWindowTitleBar.IsCustomizationSupported: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"IXP=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // Widgets + // NOTE: WidgetManager requires MSIX package identity AND the WinAppSDK Framework package. + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[Widgets]\n"; + + try + { + auto widgetManager = winrt::Microsoft::Windows::Widgets::Providers::WidgetManager::GetDefault(); + auto widgets = widgetManager.GetWidgetInfos(); + message << L" WidgetManager.GetWidgetInfos: count = " << widgets.size() << L"\n"; + log << L"Widgets=count_" << widgets.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" WidgetManager.GetDefault: 0x" << std::hex << ex.code() << std::dec + << L" (requires package identity and framework-dependent deployment)\n"; + log << L"Widgets=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // AI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[AI]\n"; + + try + { + auto readyState = winrt::Microsoft::Windows::AI::Text::LanguageModel::GetReadyState(); + std::wstring stateStr; + switch (readyState) + { + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::Ready: + stateStr = L"Ready"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotReady: + stateStr = L"NotReady"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotSupportedOnCurrentSystem: + stateStr = L"NotSupportedOnCurrentSystem"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::DisabledByUser: + stateStr = L"DisabledByUser"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::CapabilityMissing: + stateStr = L"CapabilityMissing"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotCompatibleWithSystemHardware: + stateStr = L"NotCompatibleWithSystemHardware"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::OSUpdateNeeded: + stateStr = L"OSUpdateNeeded"; + break; + default: + stateStr = std::to_wstring(static_cast(readyState)); + break; + } + message << L" LanguageModel.GetReadyState: " << stateStr << L"\n"; + log << L"AI=" << stateStr << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" LanguageModel.GetReadyState: 0x" << std::hex << ex.code() << std::dec + << L" (expected on non-AI hardware)\n"; + log << L"AI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // ML + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[ML]\n"; + + try + { + auto catalog = winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog::GetDefault(); + auto providers = catalog.FindAllProviders(); + message << L" ExecutionProviderCatalog.FindAllProviders: count = " << providers.size() << L"\n"; + log << L"ML=providers_" << providers.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" ExecutionProviderCatalog: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"ML=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // WinUI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[WinUI]\n"; + + try + { + auto cornerRadius = winrt::Microsoft::UI::Xaml::CornerRadiusHelper::FromUniformRadius(4.0); + message << L" CornerRadiusHelper.FromUniformRadius(4.0): TopLeft=" + << cornerRadius.TopLeft << L" BottomRight=" << cornerRadius.BottomRight << L"\n"; + log << L"WinUI=TopLeft_" << cornerRadius.TopLeft + << L"_BottomRight_" << cornerRadius.BottomRight << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" CornerRadiusHelper: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"WinUI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + log << L"Result=SUCCESS" << std::endl; + log.close(); + + MessageBoxW( + nullptr, + message.str().c_str(), + L"WinAppSDK CMake Smoke Test", + MB_OK | MB_ICONINFORMATION + ); + } + catch (winrt::hresult_error const& ex) + { + log << L"Error=0x" << std::hex << static_cast(ex.code()) << std::endl; + log.close(); + std::wostringstream err; + err << L"WinRT error 0x" << std::hex << ex.code() << L"\n" << ex.message().c_str(); + MessageBoxW( + nullptr, + err.str().c_str(), + L"WinAppSDK Error", + MB_OK | MB_ICONERROR + ); + return 1; + } + + return 0; +} diff --git a/Samples/CMake/Metapackage/UnpackagedSelfContained/CMakeLists.txt b/Samples/CMake/Metapackage/UnpackagedSelfContained/CMakeLists.txt new file mode 100644 index 000000000..19b394b4b --- /dev/null +++ b/Samples/CMake/Metapackage/UnpackagedSelfContained/CMakeLists.txt @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------------------------------------------------- +# Metapackage_UnpackagedSelfContained +# Unpackaged + Self-contained. WindowsPackageType=None + WindowsAppSDKSelfContained=TRUE. +#---------------------------------------------------------------------------------------------------------------------- +project(Metapackage_UnpackagedSelfContained LANGUAGES CXX) + +add_executable(Metapackage_UnpackagedSelfContained WIN32 + main.cpp +) + +set_target_properties(Metapackage_UnpackagedSelfContained PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + # Unpackaged: no MSIX. WindowsPackageType=None disables MSIX-only auto-inits. + WindowsPackageType "None" + # One property — every basic component target resolves to _SelfContained. + WindowsAppSDKSelfContained TRUE +) + +# Single link entry — bare component targets inside the umbrella resolve to _SelfContained. +target_link_libraries(Metapackage_UnpackagedSelfContained + PRIVATE + Microsoft.WindowsAppSDK +) + +wasdk_post_build_copy(Metapackage_UnpackagedSelfContained) + +# No wasdk_generate_appx_manifest() — this is an unpackaged exe. diff --git a/Samples/CMake/Metapackage/UnpackagedSelfContained/main.cpp b/Samples/CMake/Metapackage/UnpackagedSelfContained/main.cpp new file mode 100644 index 000000000..28e38208d --- /dev/null +++ b/Samples/CMake/Metapackage/UnpackagedSelfContained/main.cpp @@ -0,0 +1,280 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include +#include +#include +#include + +// WinRT base +#include + +// Foundation - EnvironmentManager, PowerManager +#include +#include + +// DWrite - DWriteCore text rendering engine +#include + +// IXP (InteractiveExperiences) - AppWindowTitleBar customization support +#include + +// Widgets - WidgetManager provider API +#include + +// AI - LanguageModel readiness check +#include +#include + +// ML - Windows ML ExecutionProvider catalog +#include + +// WinUI - XAML CornerRadiusHelper +#pragma push_macro("GetCurrentTime") +#undef GetCurrentTime +#include +#pragma pop_macro("GetCurrentTime") + +int WINAPI wWinMain( + _In_ HINSTANCE, + _In_opt_ HINSTANCE, + _In_ PWSTR, + _In_ int) +{ + wchar_t tempPath[MAX_PATH]{}; + GetTempPathW(MAX_PATH, tempPath); + std::wstring logPath = std::wstring(tempPath) + L"CMake_UnpackagedSC.log"; + std::wofstream log(logPath, std::ios::trunc); + + try + { + winrt::init_apartment(winrt::apartment_type::single_threaded); + + std::wostringstream message; + message << L"Metapackage Sample: Unpackaged Self-Contained App (CMake)\n\n"; + + //-------------------------------------------------------------------------------------------------------------- + // Foundation + //-------------------------------------------------------------------------------------------------------------- + message << L"[Foundation]\n"; + + if (winrt::Microsoft::Windows::System::EnvironmentManager::IsSupported()) + { + auto envManager = winrt::Microsoft::Windows::System::EnvironmentManager::GetForProcess(); + auto value = envManager.GetEnvironmentVariable(L"PROCESSOR_ARCHITECTURE"); + message << L" EnvironmentManager: Supported\n" + << L" PROCESSOR_ARCHITECTURE: " << std::wstring(value) << L"\n"; + log << L"Foundation=Supported" << std::endl; + } + else + { + message << L" EnvironmentManager: Not supported\n"; + log << L"Foundation=NotSupported" << std::endl; + } + + namespace Power = winrt::Microsoft::Windows::System::Power; + + auto batteryStatus = Power::PowerManager::BatteryStatus(); + message << L" BatteryStatus: "; + switch (batteryStatus) + { + case Power::BatteryStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::BatteryStatus::Discharging: + message << L"Discharging"; + break; + case Power::BatteryStatus::Idle: + message << L"Idle"; + break; + case Power::BatteryStatus::Charging: + message << L"Charging"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + auto powerSupply = Power::PowerManager::PowerSupplyStatus(); + message << L" PowerSupplyStatus: "; + switch (powerSupply) + { + case Power::PowerSupplyStatus::NotPresent: + message << L"NotPresent"; + break; + case Power::PowerSupplyStatus::Inadequate: + message << L"Inadequate"; + break; + case Power::PowerSupplyStatus::Adequate: + message << L"Adequate"; + break; + default: + message << L"Unknown"; + break; + } + message << L"\n"; + + message << L" RemainingChargePercent: " << Power::PowerManager::RemainingChargePercent() << L"%\n"; + + //-------------------------------------------------------------------------------------------------------------- + // DWrite + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[DWrite]\n"; + + winrt::com_ptr dwriteFactory; + HRESULT hr = DWriteCoreCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(dwriteFactory.put()) + ); + message << L" DWriteCoreCreateFactory: " << (SUCCEEDED(hr) ? L"Loaded" : L"Failed") << L"\n"; + log << (SUCCEEDED(hr) ? L"DWrite=Loaded" : L"DWrite=Failed") << std::endl; + + //-------------------------------------------------------------------------------------------------------------- + // IXP (InteractiveExperiences) + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[InteractiveExperiences]\n"; + + try + { + bool isSupported = winrt::Microsoft::UI::Windowing::AppWindowTitleBar::IsCustomizationSupported(); + message << L" AppWindowTitleBar.IsCustomizationSupported: " << (isSupported ? L"true" : L"false") << L"\n"; + log << (isSupported ? L"IXP=true" : L"IXP=false") << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" AppWindowTitleBar.IsCustomizationSupported: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"IXP=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // Widgets + // NOTE: WidgetManager requires MSIX package identity AND the WinAppSDK Framework package. + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[Widgets]\n"; + + try + { + auto widgetManager = winrt::Microsoft::Windows::Widgets::Providers::WidgetManager::GetDefault(); + auto widgets = widgetManager.GetWidgetInfos(); + message << L" WidgetManager.GetWidgetInfos: count = " << widgets.size() << L"\n"; + log << L"Widgets=count_" << widgets.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" WidgetManager.GetDefault: 0x" << std::hex << ex.code() << std::dec + << L" (requires package identity and framework-dependent deployment)\n"; + log << L"Widgets=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // AI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[AI]\n"; + + try + { + auto readyState = winrt::Microsoft::Windows::AI::Text::LanguageModel::GetReadyState(); + std::wstring stateStr; + switch (readyState) + { + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::Ready: + stateStr = L"Ready"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotReady: + stateStr = L"NotReady"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotSupportedOnCurrentSystem: + stateStr = L"NotSupportedOnCurrentSystem"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::DisabledByUser: + stateStr = L"DisabledByUser"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::CapabilityMissing: + stateStr = L"CapabilityMissing"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::NotCompatibleWithSystemHardware: + stateStr = L"NotCompatibleWithSystemHardware"; + break; + case winrt::Microsoft::Windows::AI::AIFeatureReadyState::OSUpdateNeeded: + stateStr = L"OSUpdateNeeded"; + break; + default: + stateStr = std::to_wstring(static_cast(readyState)); + break; + } + message << L" LanguageModel.GetReadyState: " << stateStr << L"\n"; + log << L"AI=" << stateStr << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" LanguageModel.GetReadyState: 0x" << std::hex << ex.code() << std::dec + << L" (expected on non-AI hardware)\n"; + log << L"AI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // ML + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[ML]\n"; + + try + { + auto catalog = winrt::Microsoft::Windows::AI::MachineLearning::ExecutionProviderCatalog::GetDefault(); + auto providers = catalog.FindAllProviders(); + message << L" ExecutionProviderCatalog.FindAllProviders: count = " << providers.size() << L"\n"; + log << L"ML=providers_" << providers.size() << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" ExecutionProviderCatalog: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"ML=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + //-------------------------------------------------------------------------------------------------------------- + // WinUI + //-------------------------------------------------------------------------------------------------------------- + message << L"\n[WinUI]\n"; + + try + { + auto cornerRadius = winrt::Microsoft::UI::Xaml::CornerRadiusHelper::FromUniformRadius(4.0); + message << L" CornerRadiusHelper.FromUniformRadius(4.0): TopLeft=" + << cornerRadius.TopLeft << L" BottomRight=" << cornerRadius.BottomRight << L"\n"; + log << L"WinUI=TopLeft_" << cornerRadius.TopLeft + << L"_BottomRight_" << cornerRadius.BottomRight << std::endl; + } + catch (winrt::hresult_error const& ex) + { + message << L" CornerRadiusHelper: 0x" << std::hex << ex.code() << std::dec << L"\n"; + log << L"WinUI=0x" << std::hex << static_cast(ex.code()) << std::dec << std::endl; + } + + log << L"Result=SUCCESS" << std::endl; + log.close(); + + MessageBoxW( + nullptr, + message.str().c_str(), + L"WinAppSDK CMake Smoke Test", + MB_OK | MB_ICONINFORMATION + ); + } + catch (winrt::hresult_error const& ex) + { + log << L"Error=0x" << std::hex << static_cast(ex.code()) << std::endl; + log.close(); + std::wostringstream err; + err << L"WinRT error 0x" << std::hex << ex.code() << L"\n" << ex.message().c_str(); + MessageBoxW( + nullptr, + err.str().c_str(), + L"WinAppSDK Error", + MB_OK | MB_ICONERROR + ); + return 1; + } + + return 0; +} diff --git a/Samples/CMake/PackagedFrameworkDependent/CMakeLists.txt b/Samples/CMake/PackagedFrameworkDependent/CMakeLists.txt index aa697bcd6..40cf32d8f 100644 --- a/Samples/CMake/PackagedFrameworkDependent/CMakeLists.txt +++ b/Samples/CMake/PackagedFrameworkDependent/CMakeLists.txt @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------------------------------------------------- -# PackagedFrameworkDependent - Framework-dependent deployment with MSIX packaging +# PackagedFrameworkDependent - Framework-dependent deployment with MSIX packaging (new model) #---------------------------------------------------------------------------------------------------------------------- project(PackagedFrameworkDependent LANGUAGES CXX) @@ -13,25 +13,26 @@ set_target_properties(PackagedFrameworkDependent PROPERTIES # DeploymentManager auto-init is on by default for packaged framework-dependent apps (WindowsPackageType=MSIX). # Setting it explicitly here as an example of property usage, but it could be omitted since TRUE is the default. WindowsAppSdkDeploymentManagerInitialize TRUE + # WindowsAppSDKSelfContained unset (default FALSE) → every bare WindowsAppSDK. + # target resolves to its _Framework variant. ) target_link_libraries(PackagedFrameworkDependent PRIVATE - Microsoft.WindowsAppSDK.Foundation_Framework + Microsoft.WindowsAppSDK.Foundation Microsoft.WindowsAppSDK.InteractiveExperiences - Microsoft.WindowsAppSDK.DWrite_Framework - Microsoft.WindowsAppSDK.Widgets_Framework - Microsoft.WindowsAppSDK.AI_Framework - Microsoft.WindowsAppSDK.ML_Framework - Microsoft.WindowsAppSDK.WinUI_Framework + Microsoft.WindowsAppSDK.DWrite + Microsoft.WindowsAppSDK.Widgets + Microsoft.WindowsAppSDK.AI + Microsoft.WindowsAppSDK.ML + Microsoft.WindowsAppSDK.WinUI ) -post_build_runtime_dll_copy(PackagedFrameworkDependent) +wasdk_post_build_copy(PackagedFrameworkDependent) # Generate AppxManifest.xml with framework PackageDependency auto-injected wasdk_generate_appx_manifest( TARGET PackagedFrameworkDependent - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppxManifest.xml" IDENTITY_NAME "CMake-PackagedFrameworkDependent" IDENTITY_PUBLISHER "CN=TestPublisher" IDENTITY_VERSION "1.0.0.0" diff --git a/Samples/CMake/PackagedFrameworkDependent/main.cpp b/Samples/CMake/PackagedFrameworkDependent/main.cpp index 073eeb6e3..5742953f0 100644 --- a/Samples/CMake/PackagedFrameworkDependent/main.cpp +++ b/Samples/CMake/PackagedFrameworkDependent/main.cpp @@ -191,7 +191,7 @@ int WINAPI wWinMain( } //-------------------------------------------------------------------------------------------------------------- - // Widgets + // Widgets // NOTE: WidgetManager requires MSIX package identity AND the WinAppSDK Framework package //-------------------------------------------------------------------------------------------------------------- message << L"\n[Widgets]\n"; @@ -299,7 +299,7 @@ int WINAPI wWinMain( MessageBoxW( nullptr, message.str().c_str(), - L"WinAppSDK CMake Test", + L"WinAppSDK CMake Smoke Test", MB_OK | MB_ICONINFORMATION ); } diff --git a/Samples/CMake/PackagedSelfContained/CMakeLists.txt b/Samples/CMake/PackagedSelfContained/CMakeLists.txt index 2b66a31c6..3bba795bc 100644 --- a/Samples/CMake/PackagedSelfContained/CMakeLists.txt +++ b/Samples/CMake/PackagedSelfContained/CMakeLists.txt @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------------------------------------------------- -# PackagedSelfContained - Self-contained deployment with MSIX packaging +# PackagedSelfContained - Self-contained deployment with MSIX packaging (new model) #---------------------------------------------------------------------------------------------------------------------- project(PackagedSelfContained LANGUAGES CXX) @@ -9,21 +9,22 @@ add_executable(PackagedSelfContained WIN32 set_target_properties(PackagedSelfContained PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + # One property — every bare WindowsAppSDK. target resolves to its _SelfContained variant. + WindowsAppSDKSelfContained TRUE ) target_link_libraries(PackagedSelfContained PRIVATE - Microsoft.WindowsAppSDK.Foundation_SelfContained - Microsoft.WindowsAppSDK.InteractiveExperiences_SelfContained - Microsoft.WindowsAppSDK.DWrite_SelfContained - Microsoft.WindowsAppSDK.Widgets_SelfContained - Microsoft.WindowsAppSDK.AI_SelfContained - Microsoft.WindowsAppSDK.ML_SelfContained - Microsoft.WindowsAppSDK.WinUI_SelfContained + Microsoft.WindowsAppSDK.Foundation + Microsoft.WindowsAppSDK.InteractiveExperiences + Microsoft.WindowsAppSDK.DWrite + Microsoft.WindowsAppSDK.Widgets + Microsoft.WindowsAppSDK.AI + Microsoft.WindowsAppSDK.ML + Microsoft.WindowsAppSDK.WinUI ) -post_build_runtime_dll_copy(PackagedSelfContained) -post_build_selfcontained_dll_copy(PackagedSelfContained) +wasdk_post_build_copy(PackagedSelfContained) # Copy AppxManifest.xml and Logo to the output directory for MSIX registration add_custom_command(TARGET PackagedSelfContained POST_BUILD diff --git a/Samples/CMake/PackagedSelfContained/main.cpp b/Samples/CMake/PackagedSelfContained/main.cpp index 869396787..319568281 100644 --- a/Samples/CMake/PackagedSelfContained/main.cpp +++ b/Samples/CMake/PackagedSelfContained/main.cpp @@ -278,7 +278,7 @@ int WINAPI wWinMain( MessageBoxW( nullptr, message.str().c_str(), - L"WinAppSDK CMake Test", + L"WinAppSDK CMake Smoke Test", MB_OK | MB_ICONINFORMATION ); } diff --git a/Samples/CMake/UnpackagedFrameworkDependent/CMakeLists.txt b/Samples/CMake/UnpackagedFrameworkDependent/CMakeLists.txt index e7197af06..3081dac78 100644 --- a/Samples/CMake/UnpackagedFrameworkDependent/CMakeLists.txt +++ b/Samples/CMake/UnpackagedFrameworkDependent/CMakeLists.txt @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------------------------------------------------- -# UnpackagedFrameworkDependent - Framework-dependent deployment, no MSIX packaging +# UnpackagedFrameworkDependent - Framework-dependent deployment, no MSIX packaging (new model) #---------------------------------------------------------------------------------------------------------------------- project(UnpackagedFrameworkDependent LANGUAGES CXX) @@ -12,19 +12,21 @@ set_target_properties(UnpackagedFrameworkDependent PROPERTIES # Unpackaged app: set PackageType to None so bootstrap auto-init is enabled by default WindowsPackageType "None" # Bootstrap auto-init is on by default for unpackaged framework-dependent apps (WindowsPackageType=None). - # Setting it explicitly here as an example of property usage, it can be ommitted otherwise. + # Setting it explicitly here as an example of property usage, it can be omitted otherwise. WindowsAppSdkBootstrapInitialize TRUE + # WindowsAppSDKSelfContained unset (default FALSE) → every bare WindowsAppSDK. + # target resolves to its _Framework variant. ) target_link_libraries(UnpackagedFrameworkDependent PRIVATE - Microsoft.WindowsAppSDK.Foundation_Framework + Microsoft.WindowsAppSDK.Foundation Microsoft.WindowsAppSDK.InteractiveExperiences - Microsoft.WindowsAppSDK.DWrite_Framework - Microsoft.WindowsAppSDK.Widgets_Framework - Microsoft.WindowsAppSDK.AI_Framework - Microsoft.WindowsAppSDK.ML_Framework - Microsoft.WindowsAppSDK.WinUI_Framework + Microsoft.WindowsAppSDK.DWrite + Microsoft.WindowsAppSDK.Widgets + Microsoft.WindowsAppSDK.AI + Microsoft.WindowsAppSDK.ML + Microsoft.WindowsAppSDK.WinUI ) -post_build_runtime_dll_copy(UnpackagedFrameworkDependent) +wasdk_post_build_copy(UnpackagedFrameworkDependent) diff --git a/Samples/CMake/UnpackagedFrameworkDependent/main.cpp b/Samples/CMake/UnpackagedFrameworkDependent/main.cpp index 8a3780caf..af22ebc61 100644 --- a/Samples/CMake/UnpackagedFrameworkDependent/main.cpp +++ b/Samples/CMake/UnpackagedFrameworkDependent/main.cpp @@ -278,7 +278,7 @@ int WINAPI wWinMain( MessageBoxW( nullptr, message.str().c_str(), - L"WinAppSDK CMake Test", + L"WinAppSDK CMake Smoke Test", MB_OK | MB_ICONINFORMATION ); } diff --git a/Samples/CMake/UnpackagedSelfContained/CMakeLists.txt b/Samples/CMake/UnpackagedSelfContained/CMakeLists.txt index 9bcd51955..4f17fe5de 100644 --- a/Samples/CMake/UnpackagedSelfContained/CMakeLists.txt +++ b/Samples/CMake/UnpackagedSelfContained/CMakeLists.txt @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------------------------------------------------- -# UnpackagedSelfContained - Self-contained deployment, no MSIX packaging +# UnpackagedSelfContained - Self-contained deployment, no MSIX packaging (new model) #---------------------------------------------------------------------------------------------------------------------- project(UnpackagedSelfContained LANGUAGES CXX) @@ -9,18 +9,22 @@ add_executable(UnpackagedSelfContained WIN32 set_target_properties(UnpackagedSelfContained PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + # Unpackaged: no MSIX. Disables MSIX-only auto-inits and skips the + # AppxManifest validation in wasdk_post_build_copy(). + WindowsPackageType "None" + # One property — every bare WindowsAppSDK. target resolves to its _SelfContained variant. + WindowsAppSDKSelfContained TRUE ) target_link_libraries(UnpackagedSelfContained PRIVATE - Microsoft.WindowsAppSDK.Foundation_SelfContained - Microsoft.WindowsAppSDK.InteractiveExperiences_SelfContained - Microsoft.WindowsAppSDK.DWrite_SelfContained - Microsoft.WindowsAppSDK.Widgets_SelfContained - Microsoft.WindowsAppSDK.AI_SelfContained - Microsoft.WindowsAppSDK.ML_SelfContained - Microsoft.WindowsAppSDK.WinUI_SelfContained + Microsoft.WindowsAppSDK.Foundation + Microsoft.WindowsAppSDK.InteractiveExperiences + Microsoft.WindowsAppSDK.DWrite + Microsoft.WindowsAppSDK.Widgets + Microsoft.WindowsAppSDK.AI + Microsoft.WindowsAppSDK.ML + Microsoft.WindowsAppSDK.WinUI ) -post_build_runtime_dll_copy(UnpackagedSelfContained) -post_build_selfcontained_dll_copy(UnpackagedSelfContained) +wasdk_post_build_copy(UnpackagedSelfContained) diff --git a/Samples/CMake/UnpackagedSelfContained/main.cpp b/Samples/CMake/UnpackagedSelfContained/main.cpp index 3c8406e5a..b0e91244c 100644 --- a/Samples/CMake/UnpackagedSelfContained/main.cpp +++ b/Samples/CMake/UnpackagedSelfContained/main.cpp @@ -257,7 +257,7 @@ int WINAPI wWinMain( MessageBoxW( nullptr, message.str().c_str(), - L"WinAppSDK CMake Test", + L"WinAppSDK CMake Smoke Test", MB_OK | MB_ICONINFORMATION ); }