Browse Source

Bundle the app for macOS (.icns + Info.plist + BuildMacAppBundle target)

Avalonia's Window.Icon doesn't reach the macOS Dock, so the app needs a
proper .app bundle: an ILSpy.icns produced from the existing artwork, an
Info.plist with CFBundleIconFile=ILSpy and CFBundleIdentifier
net.sharpdevelop.ilspy, and a BuildMacAppBundle target that runs
AfterTargets="Publish" for any osx-* RuntimeIdentifier. The target lays
out the standard Contents/MacOS + Contents/Resources structure under
bin/<config>/<tfm>/<rid>/ILSpy.app/ and chmods the apphost executable
so macOS LaunchServices will accept it.

The Avalonia resource glob ('Assets/**') is told to skip the bundle
inputs since they're consumed by the OS loader rather than at runtime
via avares://. The lock files pick up RID-specific runtime asset entries
that NuGet adds when an osx RID is in the project's RuntimeIdentifiers.
pull/3755/head
Siegfried Pammer 1 month ago
parent
commit
8abf3259e1
  1. BIN
      ILSpy/Assets/ILSpy.icns
  2. 32
      ILSpy/Assets/macos/Info.plist
  3. 39
      ILSpy/ILSpy.csproj

BIN
ILSpy/Assets/ILSpy.icns

Binary file not shown.

32
ILSpy/Assets/macos/Info.plist

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>ILSpy</string>
<key>CFBundleDisplayName</key>
<string>ILSpy</string>
<key>CFBundleIdentifier</key>
<string>net.sharpdevelop.ilspy</string>
<key>CFBundleVersion</key>
<string>10.1.0</string>
<key>CFBundleShortVersionString</key>
<string>10.1</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>ILSpy</string>
<key>CFBundleIconFile</key>
<string>ILSpy</string>
<key>LSMinimumSystemVersion</key>
<string>11.0</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) ic#code. Licensed under the MIT license.</string>
</dict>
</plist>

39
ILSpy/ILSpy.csproj

@ -2,6 +2,10 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<!-- RIDs we publish the app for. Declared here (not solution-wide) so the lock
file stays in sync for these targets without forcing per-RID restore onto
the ILSpyCmd tool (PackAsTool + GeneratePackageOnBuild) or the test projects. -->
<RuntimeIdentifiers>win-x64;win-arm64;linux-x64;osx-arm64</RuntimeIdentifiers>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
@ -32,6 +36,10 @@
<ItemGroup> <ItemGroup>
<AvaloniaResource Remove="Assets\ILSpy-Large.ico" /> <AvaloniaResource Remove="Assets\ILSpy-Large.ico" />
<AvaloniaResource Remove="Assets\ILSpy.pdn" /> <AvaloniaResource Remove="Assets\ILSpy.pdn" />
<!-- macOS bundle inputs: copied into ILSpy.app at publish-time by BuildMacAppBundle.
Excluded from avares:// because they're consumed by the OS loader, not the app. -->
<AvaloniaResource Remove="Assets\ILSpy.icns" />
<AvaloniaResource Remove="Assets\macos\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -116,4 +124,35 @@
<PropertyGroup Condition="'$(Configuration)' == 'Debug' AND $([MSBuild]::IsOSPlatform('Windows'))"> <PropertyGroup Condition="'$(Configuration)' == 'Debug' AND $([MSBuild]::IsOSPlatform('Windows'))">
<DefineConstants>$(DefineConstants);WINDOWS</DefineConstants> <DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
</PropertyGroup> </PropertyGroup>
<!-- macOS .app bundle.
The Avalonia Window.Icon property doesn't reach the Dock on macOS; the Dock
reads CFBundleIconFile from Info.plist and loads <name>.icns from Resources/.
Bundle layout under bin/<config>/<tfm>/<rid>/:
ILSpy.app/Contents/Info.plist
ILSpy.app/Contents/MacOS/<published files, with apphost made executable>
ILSpy.app/Contents/Resources/ILSpy.icns
Trigger: any osx-* RuntimeIdentifier after the standard Publish target. -->
<Target Name="BuildMacAppBundle"
AfterTargets="Publish"
Condition="$(RuntimeIdentifier.StartsWith('osx-'))">
<PropertyGroup>
<_MacBundleRoot>$([System.IO.Path]::GetFullPath('$(PublishDir)..'))/$(AssemblyName).app</_MacBundleRoot>
<_MacBundleContents>$(_MacBundleRoot)/Contents</_MacBundleContents>
</PropertyGroup>
<ItemGroup>
<_MacPublishFiles Include="$(PublishDir)**/*" />
</ItemGroup>
<RemoveDir Directories="$(_MacBundleRoot)" />
<MakeDir Directories="$(_MacBundleContents);$(_MacBundleContents)/MacOS;$(_MacBundleContents)/Resources" />
<Copy SourceFiles="@(_MacPublishFiles)"
DestinationFiles="@(_MacPublishFiles->'$(_MacBundleContents)/MacOS/%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="$(MSBuildProjectDirectory)/Assets/ILSpy.icns"
DestinationFolder="$(_MacBundleContents)/Resources" />
<Copy SourceFiles="$(MSBuildProjectDirectory)/Assets/macos/Info.plist"
DestinationFolder="$(_MacBundleContents)" />
<Exec Command="chmod +x &quot;$(_MacBundleContents)/MacOS/$(AssemblyName)&quot;"
Condition="!$([MSBuild]::IsOSPlatform('Windows'))" />
<Message Importance="high" Text="macOS bundle written to $(_MacBundleRoot)" />
</Target>
</Project> </Project>

Loading…
Cancel
Save