Cross-platform support and menu items for GH

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?

Related topic here: System.Drawing.Common not compatible with macOS anymore - #2 by curtisw

But the issue seems unresolved.

Hi @xliotx,

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.

Hope this helps!

Thanks for the reply.

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?

@curtisw Also, I noticed there’re multiple myplugin.gha files in different folders: net48, net7, net7-windows etc.

When doing the release, how should I include them into one yak package so that users from different platform can download and use it?

(I’m not using the yak auto-build from VS, as it doesn’t allow me to add an icon to show in PackageManager).


Additionally, there’s a bug that the filetype in Windows Explorer shows Rhino9.Yak.Package

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.

(I created a new project with the template, and move code little by little)

To be specific:


If I use System.Byte[] to store the image, it cannot be assigned to Bitmap. But if I stored it as System.Drawing.Bitmap, it cannot be loaded.

This again make the developer to manage two different version of code…

Not sure if I’m correct here. But could you update the example repo to show us how to embed images for GH component’s icon in the correct way?

Thank you.

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.

Thanks! Could you also please check my post above?
@curtisw

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.

Let me know if you run into any further issues.

Thanks for helping flush this out!