diff --git a/src/.nuspec/Uno.Resizetizer.targets b/src/.nuspec/Uno.Resizetizer.targets
index f7bedd55..2df8738c 100644
--- a/src/.nuspec/Uno.Resizetizer.targets
+++ b/src/.nuspec/Uno.Resizetizer.targets
@@ -13,40 +13,44 @@
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.ResizetizeImages_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.DetectInvalidResourceOutputFilenamesTask_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.CreatePartialInfoPlistTask_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GenerateSplashAndroidResources_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GenerateSplashStoryboard_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GenerateSplashAssets_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GetUnoAssetPath_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GeneratePackageAppxManifest_v0" />
+ AssemblyFile="$(_UnoResizetizerTaskAssemblyName)"
+ TaskName="Uno.Resizetizer.GenerateWasmSplashAssets_v0" />
+
+
@@ -248,6 +252,11 @@
+
+
+ <_WindowIconExtension Include="$(_ResizetizerIntermediateOutputRoot)Uno.Resizetizer.WindowIconExtensions.g.cs" />
+
+
@@ -267,29 +276,29 @@
+ Condition="'$(_ResizetizerIsCompatibleApp)' == 'True' And '$(DisableResizetizer)' != 'true'"
+ BeforeTargets="$(ResizetizeCollectItemsBeforeTargets)"
+ AfterTargets="$(ResizetizeCollectItemsAfterTargets)">
+ TaskParameter="TargetOutputs"
+ ItemName="ImportedUnoItem" />
+ Include="@(ImportedUnoItem)"
+ Condition="'%(ImportedUnoItem.ItemGroupName)' == 'UnoImage'"/>
+ Include="@(ImportedUnoItem)"
+ Condition="'%(ImportedUnoItem.ItemGroupName)' == 'UnoIcon'" />
+ Include="@(ImportedUnoItem)"
+ Condition="'%(ImportedUnoItem.ItemGroupName)' == 'UnoAsset'" />
+ Include="@(ImportedUnoItem)"
+ Condition="'%(ImportedUnoItem.ItemGroupName)' == 'UnoSplashScreen'" />
@@ -298,7 +307,7 @@
+ Text ="The UnoIcon.Link property will be ignored." />
@@ -308,16 +317,16 @@
+ File="$(_ResizetizerInputsFile)"
+ Lines="@(UnoImage->'File=%(Identity);Link=%(Link);BaseSize=%(BaseSize);Resize=%(Resize);TintColor=%(TintColor);Color=%(Color);IsAppIcon=%(IsAppIcon);ForegroundScale=%(ForegroundScale);ForegroundFile=%(ForegroundFile)')"
+ Overwrite="true"
+ WriteOnlyWhenDifferent="true" />
+ File="$(_UnoSplashInputsFile)"
+ Lines="@(UnoSplashScreen->'File=%(Identity);Link=%(Link);BaseSize=%(BaseSize);Resize=%(Resize);TintColor=%(TintColor);Color=%(Color);ForegroundScale=%(ForegroundScale)')"
+ Overwrite="true"
+ WriteOnlyWhenDifferent="true" />
@@ -328,7 +337,7 @@
Condition="%(Extension) == '.appxmanifest'"/>
+ Condition="%(Extension) == '.appxmanifest'"/>
@@ -342,9 +351,9 @@
+ ProjectDirectory="$(MSBuildProjectDirectory)"
+ ItemMetadata="$(_UnoAssetItemMetadata)"
+ Input="@(UnoAsset)">
@@ -352,12 +361,12 @@
+ Condition="'@(UnoSplashScreen)' != '' And '$(DesignTimeBuild)' != 'true'">
+ Condition="'@(UnoSplashScreen->Count())' > '1'"
+ Text="More than one 'UnoSplashScreen' is defined; only the first will be used."
+ />
+ Condition="'$(_ResizetizerIsAndroidApp)' == 'True'"
+ IntermediateOutputPath="$(_UnoIntermediateSplashScreen)"
+ UnoSplashScreen="@(UnoSplashScreen)"
+ />
$(_ResizetizerStampFile)
@@ -410,10 +419,10 @@
+ Condition="'$(_ResizetizerIsiOSApp)' == 'True' and '$(TargetPlatformIdentifier)' != 'maccatalyst'"
+ OutputFile="$(_UnoIntermediateStoryboard)"
+ UnoSplashScreen="@(UnoSplashScreen)"
+ />
<_UnoIntermediateSplashScreenFile>$(_UnoIntermediateStoryboard)
@@ -424,10 +433,10 @@
+ Condition="'$(_ResizetizerIsiOSApp)' == 'True' And '$(_UnoIntermediateSplashScreenFile)' != ''"
+ IntermediateOutputPath="$(_UnoIntermediateSplashScreen)"
+ PlistName="UnoInfo.plist"
+ Storyboard="$(_UnoIntermediateSplashScreenFile)" />
<_UnoSplashPListFiles Include="$(_UnoIntermediateSplashScreen)UnoInfo.plist" Condition="Exists('$(_UnoIntermediateSplashScreen)UnoInfo.plist')" />
@@ -441,19 +450,19 @@
+ Condition="'$(BuildSessionId)' != '' And '$(_ResizetizerIsiOSApp)' == 'True' And '$(IsMacEnabled)'=='true'"
+ SessionId="$(BuildSessionId)"
+ Files="@(_UnoAssetsToCopyToBuildServer)" />
+ Condition="'$(_ResizetizerIsUWPApp)' == 'True' Or '$(_ResizetizerIsWindowsAppSdk)' == 'True'"
+ IntermediateOutputPath="$(_UnoIntermediateSplashScreen)"
+ UnoSplashScreen="@(UnoWindowsSplash)"
+ />
<_UnoSplashAssets Include="$(_UnoIntermediateSplashScreen)**\*" />
@@ -471,26 +480,26 @@
+ BeforeTargets="$(ResizetizeBeforeTargets)"
+ DependsOnTargets="$(ResizetizeDependsOnTargets)">
+ Items="@(UnoImage->Distinct())"
+ ErrorMessage="$(_ResizetizerDefaultInvalidFilenamesErrorMessage)">
+ InputsFile="$(_ResizetizerInputsFile)"
+ Images="@(UnoImage->Distinct())">
@@ -568,8 +577,8 @@
+ Include="@(_ResizetizerCollectedBundleResourceImages)"
+ Condition="'@(_ResizetizerCollectedBundleResourceImages->Contains('Assets.xcassets'))' == 'True' and '%(_ResizetizerCollectedBundleResourceImages.Identity)' != ''">
Assets.xcassets\$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName(%(_ResizetizerCollectedBundleResourceImages.Identity)))))\%(_ResizetizerCollectedBundleResourceImages.Filename)%(_ResizetizerCollectedBundleResourceImages.Extension)
Assets.xcassets\$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName(%(_ResizetizerCollectedBundleResourceImages.Identity)))))\%(_ResizetizerCollectedBundleResourceImages.Filename)%(_ResizetizerCollectedBundleResourceImages.Extension)
Assets.xcassets\$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName(%(_ResizetizerCollectedBundleResourceImages.Identity)))))\%(_ResizetizerCollectedBundleResourceImages.Filename)%(_ResizetizerCollectedBundleResourceImages.Extension)
@@ -584,9 +593,9 @@
+ Condition="'$(BuildSessionId)' != '' And '$(_ResizetizerIsiOSApp)' == 'True' And '$(IsMacEnabled)'=='true'"
+ SessionId="$(BuildSessionId)"
+ Files="@(_UnoImagesToCopyToBuildServer)" />
$(AppIconPath)
@@ -602,18 +611,18 @@
+ on "_ValidatePresenceOfAppxManifestItems" and we need to get in before then. -->
+ BeforeTargets="_ValidatePresenceOfAppxManifestItems"
+ DependsOnTargets="UnoGeneratePackageAppxManifest"
+ Condition="'$(_ResizetizerIsUWPApp)' == 'True' Or '$(_ResizetizerIsWindowsAppSdk)' == 'True' Or '$(_ResizetizerIsSkiaApp)' == 'True'" />
+ Inputs="$(MSBuildThisFileFullPath);$(_UnoResizetizerTaskAssemblyName);$(_ResizetizerInputsFile);$(_UnoSplashInputsFile);@(AppxManifest);@(_UnoAppxManifest)"
+ Outputs="$(_UnoManifestStampFile);$(_UnoIntermediateManifest)Package.appxmanifest">
@@ -622,15 +631,15 @@
+ IntermediateOutputPath="$(_UnoIntermediateManifest)"
+ AppxManifest="@(AppxManifest);@(_UnoAppxManifest);@(_SkiaManifest)"
+ GeneratedFilename="Package.appxmanifest"
+ ApplicationId="$(_MauiWindowsApplicationId)"
+ ApplicationDisplayVersion="$(ApplicationDisplayVersion)"
+ ApplicationVersion="$(ApplicationVersion)"
+ ApplicationTitle="$(ApplicationTitle)"
+ AppIcon="@(UnoImage->WithMetadataValue('IsAppIcon', 'true'))"
+ SplashScreen="@(UnoSplashScreen)" />
@@ -643,13 +652,13 @@
@@ -670,4 +679,20 @@
+
+
+
+
+
+
+
+
diff --git a/src/Resizetizer/src/WindowIconGeneratorTask.cs b/src/Resizetizer/src/WindowIconGeneratorTask.cs
new file mode 100644
index 00000000..bd00ec90
--- /dev/null
+++ b/src/Resizetizer/src/WindowIconGeneratorTask.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Uno.Resizetizer;
+
+public class WindowIconGeneratorTask_V0 : Task
+{
+ private const string FileName = "Uno.Resizetizer.WindowIconExtensions.g.cs";
+
+ public ITaskItem[] UnoIcons { get; set; }
+
+ [Required]
+ public string IntermediateOutputDirectory { get; set; }
+
+ [Output]
+ public ITaskItem[] GeneratedClass { get; private set; } = Array.Empty();
+
+ public override bool Execute()
+ {
+ if (UnoIcons is null || UnoIcons.Length == 0)
+ {
+ return true;
+ }
+
+ if(string.IsNullOrEmpty(IntermediateOutputDirectory))
+ {
+ Log.LogError("The IntermediateOutputDirectory (typically the obj directory) is a required parameter but was null or empty.");
+ return false;
+ }
+
+ var iconPath = UnoIcons[0].ItemSpec;
+ var iconName = Path.GetFileNameWithoutExtension(iconPath);
+
+ var code = @$"//------------------------------------------------------------------------------
+//
+// This code was auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Uno.Resizetizer
+{{
+ public static class WindowExtensions
+ {{
+ ///
+ /// This will set the Window Icon for the given using
+ /// the provided UnoIcon.
+ ///
+ public static void SetWindowIcon(this global::Microsoft.UI.Xaml.Window window)
+ {{
+#if WINDOWS && !HAS_UNO
+ var hWnd =
+ global::WinRT.Interop.WindowNative.GetWindowHandle(window);
+
+ // Retrieve the WindowId that corresponds to hWnd.
+ global::Microsoft.UI.WindowId windowId =
+ global::Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
+
+ // Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
+ global::Microsoft.UI.Windowing.AppWindow appWindow =
+ global::Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
+ appWindow.SetIcon(""{iconName}.ico"");
+#endif
+ }}
+ }}
+}}";
+
+ if(!Directory.Exists(IntermediateOutputDirectory))
+ {
+ Directory.CreateDirectory(IntermediateOutputDirectory);
+ }
+
+ var item = new TaskItem(Path.Combine(IntermediateOutputDirectory, FileName));
+ File.WriteAllText(item.ItemSpec, code);
+ GeneratedClass = new [] { item };
+ return true;
+ }
+}