Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
<!-- Work around https://github.com/dotnet/runtime/issues/109682 -->
<CETCompat>false</CETCompat>
<PublishAot>true</PublishAot>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Don’t enable AOT globally; gate it (WPF and plugin-style apps are incompatible with trimming/AOT).

NativeAOT requires trimming, and WPF trimming is disabled in the SDK; dynamic assembly loading (common in plugin systems) is also trim-incompatible. This unconditional setting will fail publish or break at runtime. Gate AOT behind an opt-in switch and exclude WPF/WinForms EXEs. (learn.microsoft.com)

Apply this minimal fix:

   <CETCompat>false</CETCompat>
-  <PublishAot>true</PublishAot>
+  <!-- Opt-in from CLI/CI: -p:EnableNativeAot=true -->
+  <EnableNativeAot>false</EnableNativeAot>
+  <PublishAot Condition="'$(EnableNativeAot)' == 'true'
+                         and '$(IsPublishable)' == 'true'
+                         and '$(OutputType)' == 'Exe'
+                         and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))
+                         and '$(RuntimeIdentifier)' != ''
+                         and '$(UseWPF)' != 'true'
+                         and '$(UseWindowsForms)' != 'true'">true</PublishAot>

Example publish: dotnet publish src/Flow.Launcher/Flow.Launcher.csproj -c Release -r win-x64 -p:EnableNativeAot=true

Note: Windows AOT also requires the “Desktop development with C++” workload on build agents/dev machines. (learn.microsoft.com)


🏁 Script executed:

#!/bin/bash
# Verify risk hotspots for AOT in this repo
set -euo pipefail

echo "Projects using WPF/WinForms:"
rg -n -g "**/*.csproj" -C1 -P '<UseWPF>\s*true|<UseWindowsForms>\s*true' || true

echo -e "\nExecutable projects and TFMs:"
rg -n -g "**/*.csproj" -C1 -P '<OutputType>\s*(WinExe|Exe)\s*</OutputType>|<TargetFrameworks?>' || true

echo -e "\nDynamic loading patterns (trim/AOT incompatible):"
rg -n -g "!**/bin/**" -g "!**/obj/**" -P '\b(Assembly\.Load|AssemblyLoadContext\.Default\.Load|LoadFrom\(|LoadFile\()' || true

Length of output: 12529


Gate Native AOT behind an opt-in switch and only for compatible executables
NativeAOT (PublishAot) must not be enabled globally—trimming is incompatible with WPF/WinForms and plugin-style assemblies. Add an EnableNativeAot flag (default false) and conditionally set <PublishAot> only when publishing an EXE targeting .NET 9.0+ with a RID and without WPF/WinForms:

   <CETCompat>false</CETCompat>
-  <PublishAot>true</PublishAot>
+  <!-- Opt-in via CLI/CI: -p:EnableNativeAot=true -->
+  <EnableNativeAot>false</EnableNativeAot>
+  <PublishAot Condition="
+      '$(EnableNativeAot)' == 'true'
+      and '$(IsPublishable)' == 'true'
+      and '$(OutputType)' == 'Exe'
+      and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))
+      and '$(RuntimeIdentifier)' != ''
+      and '$(UseWPF)' != 'true'
+      and '$(UseWindowsForms)' != 'true'">
+    true
+  </PublishAot>

Example publish command:

dotnet publish Flow.Launcher/Flow.Launcher.csproj -c Release -r win-x64 -p:EnableNativeAot=true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<PublishAot>true</PublishAot>
<PropertyGroup>
<CETCompat>false</CETCompat>
<!-- Opt-in via CLI/CI: -p:EnableNativeAot=true -->
<EnableNativeAot>false</EnableNativeAot>
<PublishAot Condition="
'$(EnableNativeAot)' == 'true'
and '$(IsPublishable)' == 'true'
and '$(OutputType)' == 'Exe'
and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))
and '$(RuntimeIdentifier)' != ''
and '$(UseWPF)' != 'true'
and '$(UseWindowsForms)' != 'true'">
true
</PublishAot>
</PropertyGroup>
🤖 Prompt for AI Agents
In Directory.Build.props around line 6, PublishAot is currently enabled
globally; add a new property <EnableNativeAot>false</EnableNativeAot> and change
the PublishAot setting to only evaluate true when publishing an executable for
.NET 9+ with a RID and explicit opt-in: check $(EnableNativeAot) == 'true',
$(OutputType) == 'Exe' (or $(IsExe) if used),
TargetFrameworkMoniker/TargetFramework starts with net9 or
TargetFrameworkVersion >= 9, and that a RuntimeIdentifier/RuntimeIdentifiers is
present, and exclude when $(UseWPF) == 'true' or $(UseWindowsForms) == 'true'
(or when WPF/WinForms SDK is detected); implement this as a conditional
PropertyGroup so the default remains false and developers can opt in via
-p:EnableNativeAot=true when publishing an EXE with a RID.

</PropertyGroup>
</Project>
12 changes: 12 additions & 0 deletions Flow.Launcher.Core/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@
"resolved": "3.4.3",
"contentHash": "REjInKnQ0OrhjjtSMPQtLtdURctCroB4L8Sd2gjTOYDysklvsdnrStx1tHS7uLv+fSyFF3aazZmo5Ka0v1oz/w=="
},
"Microsoft.DotNet.ILCompiler": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "cMwVh5hsxAhv+oMHQdgcXodt2kDpfviofBO4IXupSAHJW2vZOZOOIhvPWRGO6NeGcP8SR4OpSwktRqb0i79KFA=="
},
"Microsoft.IO.RecyclableMemoryStream": {
"type": "Direct",
"requested": "[3.0.1, )",
"resolved": "3.0.1",
"contentHash": "s/s20YTVY9r9TPfTrN5g8zPF1YhwxyqO6PxUkrYTGI2B+OGPe9AdajWZrLhFqXIvqIW23fnUE4+ztrUWNU1+9g=="
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "rd1CbIsMtVPtZNTIVD6Xydue//klYOOQIDpRgu3BHtv17AlpRs74/6QFbcYgMm/jL+naVU2T3OFLxVSLV5lQLQ=="
},
"SemanticVersioning": {
"type": "Direct",
"requested": "[3.0.0, )",
Expand Down Expand Up @@ -169,7 +181,7 @@
"resolved": "0.9.6.1",
"contentHash": "yMsurNaOxxKIjyW9pEB+tRrR1S3DFnN1+iBgKvYvXG8kW0Y6yknJeMAe/tl3+P78/2C6304TgF7aVqpqXgEQ9Q=="
},
"Nerdbank.Streams": {

Check warning on line 184 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`Nerdbank` is not a recognized word. (unrecognized-spelling)
"type": "Transitive",
"resolved": "2.12.87",
"contentHash": "oDKOeKZ865I5X8qmU3IXMyrAnssYEiYWTobPGdrqubN3RtTzEHIv+D6fwhdcfrdhPJzHjCkK/ORztR/IsnmA6g==",
Expand All @@ -179,7 +191,7 @@
"System.IO.Pipelines": "8.0.0"
}
},
"Newtonsoft.Json": {

Check warning on line 194 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`Newtonsoft` is not a recognized word. (unrecognized-spelling)
"type": "Transitive",
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
Expand All @@ -189,12 +201,12 @@
"resolved": "3.0.0",
"contentHash": "IEghs0QqWsQYH0uUmvIl0Ye6RaebWRh38eB6ToOkDnQucTYRGFOgtig0gSxlwCszTilYFz3n1ZuY762x+kDR3A=="
},
"NHotkey.Wpf": {

Check warning on line 204 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NHotkey` is not a recognized word. (unrecognized-spelling)
"type": "Transitive",
"resolved": "3.0.0",
"contentHash": "BIUKlhTG5KtFf9OQzWvkmVmktt5/FFj6AOEgag8Uf0R2YdZt5ajUzs3sVskcJcT2TztWlEHKQr1jFj3KQ0D9Nw==",
"dependencies": {
"NHotkey": "3.0.0"

Check warning on line 209 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NHotkey` is not a recognized word. (unrecognized-spelling)
}
},
"NLog": {
Expand All @@ -202,12 +214,12 @@
"resolved": "6.0.1",
"contentHash": "qDWiqy8/xdpZKtHna/645KbalwP86N2NFJEzfqhcv+Si4V2iNaEfR/dCneuF/4+Dcwl3f7jHMXj3ndWYftV3Ug=="
},
"NLog.OutputDebugString": {

Check warning on line 217 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NLog` is not a recognized word. (unrecognized-spelling)
"type": "Transitive",
"resolved": "6.0.1",
"contentHash": "wwJCQLaHVzuRf8TsXB+EEdrzVvE3dnzCSMQMDgwkw3AXp8VSp3JSVF/Q/H0oEqggKgKhPs13hh3a7svyQr4s3A==",
"dependencies": {
"NLog": "6.0.1"

Check warning on line 222 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NLog` is not a recognized word. (unrecognized-spelling)
}
},
"SharpVectors.Wpf": {
Expand Down Expand Up @@ -251,15 +263,15 @@
"flow.launcher.infrastructure": {
"type": "Project",
"dependencies": {
"Ben.Demystifier": "[0.4.1, )",

Check warning on line 266 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`Demystifier` is not a recognized word. (unrecognized-spelling)
"BitFaster.Caching": "[2.5.4, )",
"CommunityToolkit.Mvvm": "[8.4.0, )",
"Flow.Launcher.Plugin": "[4.7.0, )",
"InputSimulator": "[1.0.4, )",
"MemoryPack": "[1.21.4, )",
"Microsoft.VisualStudio.Threading": "[17.14.15, )",
"NHotkey.Wpf": "[3.0.0, )",

Check warning on line 273 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NHotkey` is not a recognized word. (unrecognized-spelling)
"NLog": "[6.0.1, )",

Check warning on line 274 in Flow.Launcher.Core/packages.lock.json

View workflow job for this annotation

GitHub Actions / Check Spelling

`NLog` is not a recognized word. (unrecognized-spelling)
"NLog.OutputDebugString": "[6.0.1, )",
"SharpVectors.Wpf": "[1.8.4.2, )",
"System.Drawing.Common": "[7.0.0, )",
Expand Down
12 changes: 12 additions & 0 deletions Flow.Launcher.Infrastructure/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@
"MemoryPack.Generator": "1.21.4"
}
},
"Microsoft.DotNet.ILCompiler": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "cMwVh5hsxAhv+oMHQdgcXodt2kDpfviofBO4IXupSAHJW2vZOZOOIhvPWRGO6NeGcP8SR4OpSwktRqb0i79KFA=="
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "rd1CbIsMtVPtZNTIVD6Xydue//klYOOQIDpRgu3BHtv17AlpRs74/6QFbcYgMm/jL+naVU2T3OFLxVSLV5lQLQ=="
},
"Microsoft.VisualStudio.Threading": {
"type": "Direct",
"requested": "[17.14.15, )",
Expand Down
12 changes: 12 additions & 0 deletions Flow.Launcher.Plugin/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
"resolved": "2024.3.0",
"contentHash": "ox5pkeLQXjvJdyAB4b2sBYAlqZGLh3PjSnP1bQNVx72ONuTJ9+34/+Rq91Fc0dG29XG9RgZur9+NcP4riihTug=="
},
"Microsoft.DotNet.ILCompiler": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "cMwVh5hsxAhv+oMHQdgcXodt2kDpfviofBO4IXupSAHJW2vZOZOOIhvPWRGO6NeGcP8SR4OpSwktRqb0i79KFA=="
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "rd1CbIsMtVPtZNTIVD6Xydue//klYOOQIDpRgu3BHtv17AlpRs74/6QFbcYgMm/jL+naVU2T3OFLxVSLV5lQLQ=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
Expand Down
12 changes: 12 additions & 0 deletions Flow.Launcher/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
"Svg": "3.0.84"
}
},
"Microsoft.DotNet.ILCompiler": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "cMwVh5hsxAhv+oMHQdgcXodt2kDpfviofBO4IXupSAHJW2vZOZOOIhvPWRGO6NeGcP8SR4OpSwktRqb0i79KFA=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Direct",
"requested": "[9.0.7, )",
Expand Down Expand Up @@ -108,6 +114,12 @@
"Microsoft.Extensions.Options": "9.0.7"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "rd1CbIsMtVPtZNTIVD6Xydue//klYOOQIDpRgu3BHtv17AlpRs74/6QFbcYgMm/jL+naVU2T3OFLxVSLV5lQLQ=="
},
"Microsoft.Toolkit.Uwp.Notifications": {
"type": "Direct",
"requested": "[7.1.3, )",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,10 @@
throw new Exception("stream is null");
}

var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());

using var reader = new StreamReader(stream);
var text = reader.ReadToEnd();

settingsList = JsonSerializer.Deserialize<IEnumerable<WindowsSetting>>(text, options);
settingsList = JsonSerializer.Deserialize(text, MyJsonContext.Default.IEnumerableWindowsSetting);
}
catch (Exception exception)
{
Expand All @@ -55,4 +52,13 @@
return settingsList ?? Enumerable.Empty<WindowsSetting>();
}
}

[JsonSourceGenerationOptions(

Check failure on line 56 in Plugins/Flow.Launcher.Plugin.WindowsSettings/Helper/JsonSettingsListHelper.cs

View workflow job for this annotation

GitHub Actions / build

The member 'Flow.Launcher.Plugin.WindowsSettings.Helper.MyJsonContext' has been annotated with 'JsonStringEnumConverter' which is not supported in native AOT. Consider using the generic 'JsonStringEnumConverter<TEnum>' instead. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1034)

Check failure on line 56 in Plugins/Flow.Launcher.Plugin.WindowsSettings/Helper/JsonSettingsListHelper.cs

View workflow job for this annotation

GitHub Actions / build

The member 'Flow.Launcher.Plugin.WindowsSettings.Helper.MyJsonContext' has been annotated with 'JsonStringEnumConverter' which is not supported in native AOT. Consider using the generic 'JsonStringEnumConverter<TEnum>' instead. (https://learn.microsoft.com/dotnet/fundamentals/syslib-diagnostics/syslib1034)
Converters = new[] { typeof(JsonStringEnumConverter) },
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase
)]
[JsonSerializable(typeof(IEnumerable<WindowsSetting>))]
internal partial class MyJsonContext : JsonSerializerContext
{
}
}
Loading