In general, I’d like to ask if it is possible to compile .gha library for both macOS and Windows on Net 7.
It is possible when targeting Rhino 7, with .NET Framework 4.8. But since Rhino 8 switches to Net 7, many things changes…
If the above question is possible, then how should I deal with things like System.Windows.Forms.ToolStripDropDown that can provide right-click menu for each component?
Please try our dotnet/visual studio 2022 grasshopper templates, it’ll show you how to set that all up in your project files. It can also (optionally) be configured to create .yak’s for Rhino 7 and multi-target for Rhino 8 with net48, net7.0, and net7.0-windows TargetFrameworks.
The instructions to get started with the templates are here.
So does it mean that if I have both net7.0 and net7.0-windows in my project files, things like Window.Forms.Tooltips or BitMap (for component icon) will be automatically adapt to macOS?
I’m actually using your suggested plugins here, but the .gha I compiled from Windows can be installed on macOS, but the plugins are not shown / and components cannot be found.
The other question is when starting with the template, if I uncheck “using WindowsForms” then the default example code with Bitmap will not work… How should I assign Assembly Icons then for both Windows and macOS?
So I spent the whole day testing bit by bit why it seems macOS’s Rhino can install the plugin but nothing is shown in GH and no error was generated.
It seems the issue is cased by the Bitmap icon?
Net Framework 4.8 uses a .resx file to manage the icon, but this doesn’t work in net7, and you need to use a embed approach to load the images.
That is correct. We include an implementation of System.Windows.Forms and System.Drawing for macOS that make all of that work.
On Mac, the net7.0 target will be used. On Windows, the net7.0-windows target will be used instead. The project templates include this section for the net7.0 target which lights up the APIs for use on Mac:
<ItemGroup Condition="!($(TargetFramework.Contains('-windows')) or $(TargetFramework.StartsWith('net4')))">
<!-- Rhino 8.11 and later you can use this -->
<!-- <FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" /> -->
<!-- Rhino 8.10 and earlier -->
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net48" Version="1.0.3" ExcludeAssets="all" GeneratePathProperty="true" />
<Reference Include="$(PkgMicrosoft_NETFramework_ReferenceAssemblies_net48)\build\.NETFramework\v4.8\System.Windows.Forms.dll" Private="False" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" ExcludeAssets="runtime" />
</ItemGroup>
You need to keep that checked so you can use Bitmap and other System.Drawing/WinForms types.
Yes, this is called multi-targeting. You can read about how to package multiple targets with yak here
Since Rhino 7 doesn’t support multi-targeting, you would have to have separate .yak packages for 7 vs 8.
Oh man, MS really messed up the new .resx editor in Visual Studio.
It should be as easy as adding the System.Resources.Extensions nuget package, and then adding the image to the resx as you have done. Unfortunately, to compile for net48 it needs to store it as this (which works for both net48 and net7.0): System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Instead of this, which only works for net7.0 or later: System.Drawing.Bitmap, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
One way to get around this is to use the old resx editor by right clicking on the .resx > open with > Managed Resources Editor (legacy), which uses the correct values. Alternatively you can edit the .resx manually to change it.
It also appears that to compile on Mac (or with dotnet tools), you need to add <GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources> to the csproj as well.
I’ve created RH-86497 to get the templates tweaked for this scenario.