I’m setting up a new Grasshopper project with the VS templates for Rhino8 (from here ). I’m not ticking WPF or WinForm as ideally I want it to be cross platform.
However opening the template straight out of box wont allow me to compile. The Grasshopper component is refering to System.Drawing.Bitmap which is not part of .NET7.
Looks like the grasshopper template component is dependent on .NET Framework 4.8, which I don’t fully understand if we’re all switching to .NET7 ?
3 Likes
Looks like the core (pun intended) of the problem is that NuGet only refers to Framework48 versions of Grasshopper and RhinoCommon.
1 Like
Semi solved by adding System.Drawing.Common to my project, which allows to compile the .net7 in windows.
In order to remove the Framework48 warnings i ended up pointing my
Grasshopper dll to C:\Program Files\Rhino 8\Plug-ins\Grasshopper\Grasshopper.dll
RhinoCommon to C:\Program Files\Rhino 8\System\netcore\RhinoCommon.dll
which I’m very sure is NOT the intended way to do it. However I’m unsure how to get .NET 7 versions of RhinoCommon.dll and Grasshopper.dll
2 Likes
TomTom
(Tom)
July 1, 2024, 11:58am
5
System.Drawing is a Nuget package in Core. I think you only need to satisfy the compiler/linker, but you don’t need to ship it. I think Eto/Rhino can handle it both for Mac and Windows. Still its not good that a template does not work out of the box.
Agreed,
I see two problems though:
Templates not working out of the box
NuGet versions of Grasshopper and RhinoCommon are not .NET 7 Compatible
TomTom
(Tom)
July 1, 2024, 12:06pm
7
Regarding 2. This is what I would have also done. There was a time before VS Templates. I think its worth to dig into the old Grasshopper SDK. Its not to hard to follow and gives a decent idea on what actually happens.
Agreed and thanks for reminding. Heard mcneel peeps say on forum that people should use the nuget packages though.
jhs
(-JHS-)
July 11, 2024, 12:02pm
9
I have tested with template and started from scratch and always ending up getting fails about assemblies…
Created Class library - C# for .net 7
Project Settings
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>1.0</Version>
<Title>UserPrincipleTest2</Title>
<Description>Description of UserPrincipleTest2</Description>
<TargetExt>.gha</TargetExt>
</PropertyGroup>
Added two classes into project (same as creating with template)
UserPrincipleTestComponent2.cs
UserPrincipleTest2Info.cs
Added references
<ItemGroup>
<Reference Include="GH_IO">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\GH_IO.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Grasshopper">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\Grasshopper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RhinoCommon">
<HintPath>..\..\..\..\Program Files\Rhino 8\System\RhinoCommon.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
Added two nuget packages
<ItemGroup>
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup>
Modify SolveInstance and input
protected override void SolveInstance(IGH_DataAccess DA)
{
bool run = false;
if (!DA.GetData(0, ref run)) { return; }
if(!run) { return; }
//Checking if User Principle works ok
string userName = Environment.UserName;
string userFullName = UserPrincipal.Current.DisplayName;
}
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddBooleanParameter("Run", "Run", "True = the tool is running and waits for changes in \"Trigger Component\" input", GH_ParamAccess.item);
}
Compile has 2 warnings and 0 errors.
Rhino GrasshopperDeveloperSettings has correct folder for automatic loading.
When adding and connecting boolean trigger into component → Solution exception:Could not load file or assembly ‘System.DirectoryServices.AccountManagement, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. The system cannot find the file specified.
FIX Round 1 Modify PropertyGroup
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>1.0</Version>
<Title>UserPrincipleTest2</Title>
<Description>Description of UserPrincipleTest2</Description>
<TargetExt>.gha</TargetExt
Addedd line--><CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
Clean + Compile with no errors.
Now we have another fail when running component in Grasshopper. Solution exception :System.DirectoryServices.AccountManagement is not supported on this platform.
Fix Round 2 Remove AccountManagement nuget package and add .netframework version as reference.
<Reference Include="System.DirectoryServices.AccountManagement">
<HintPath>..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1\System.DirectoryServices.AccountManagement.dll</HintPath>
<Private>True</Private>
</Reference>
Comment <!--<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>-->
Clean + Compile with no errors.
Failing 1. Solution exception :Could not load file or assembly ‘System.DirectoryServices.AccountManagement, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. Reference assemblies cannot be loaded for execution. (0x80131058)
File list from folder after fail
System.DirectoryServices.AccountManagement.dll
System.DirectoryServices.AccountManagement.xml
System.DirectoryServices.dll
System.DirectoryServices.Protocols.dll
System.DirectoryServices.Protocols.xml
System.DirectoryServices.x ml
UserPrincipleTest2.deps.json
UserPrincipleTest2.gha
UserPrincipleTest2.pdb
Ay ideas how to fix the issue? Can anyone get UserPrinciple working in Visual Studio - Grasshopper .net 7 component?
As I see it, you have to set copylocal to true on all dlls that are not part of the rhino package.
So your user thingies dll needs to be copied.
And then reference the system/dotnet/rhinocommon.dll instead of the system/rhinocommon.dll if building for core (.net7).
Also check if the right gha is referenced to gh. You might have one in repo/bin folder and another in gh/libraries. In that case make sure your dlls are in both.
jhs
(-JHS-)
July 11, 2024, 12:50pm
12
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
This copies all references which are not part of rhino installation.
jhs
(-JHS-)
July 11, 2024, 12:57pm
13
Mathias Sønderskov Schaltz:
As I see it, you have to set copylocal to true on all dlls that are not part of the rhino package.
So your user thingies dll needs to be copied.
And then reference the system/dotnet/rhinocommon.dll instead of the system/rhinocommon.dll if building for core (.net7).
Updated grasshopper to default settings, Rhino 8 using NetCore
Checked that grasshopper loads correct gha file
My project settings
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>1.0</Version>
<Title>UserPrincipleTest2</Title>
<Description>Description of UserPrincipleTest2</Description>
<TargetExt>.gha</TargetExt>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<Reference Include="GH_IO">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\GH_IO.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Grasshopper">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\Grasshopper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RhinoCommon">
<HintPath>..\..\..\..\Program Files\Rhino 8\System\netcore\RhinoCommon.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
</Project>
Compile ok. Getting error from component: Solution exception :System.DirectoryServices.AccountManagement is not supported on this platform.
UPDATED FILE LIST
26ÿ784 Microsoft.Win32.SystemEvents.dll
<DIR> runtimes
442ÿ640 System.Configuration.ConfigurationManager.dll
51ÿ872 System.Diagnostics.EventLog.dll
68ÿ376 System.DirectoryServices.AccountManagement.dll
129ÿ800 System.DirectoryServices.dll
71ÿ856 System.DirectoryServices.Protocols.dll
595ÿ632 System.Drawing.Common.dll
37ÿ136 System.Security.Cryptography.ProtectedData.dll
8ÿ103 UserPrincipleTest2.deps.json
6ÿ144 UserPrincipleTest2.gha
11ÿ716 UserPrincipleTest2.pdb
Looks like you are referring a .net framework dll into .net core. Did you check the compatibility of your reference (you can see that in nuget)
tor. 11. jul. 2024 15.07 skrev -JHS- via McNeel Forum <notifications@mcneel.discoursemail.com >:
jhs
(-JHS-)
July 12, 2024, 6:35am
15
None of the outputs are in .net framework.
Referenced libraies are supporting .Net 7
TomTom
(Tom)
July 12, 2024, 9:01am
16
I don’t know if it helps. But System.DirectoryServices.AccountManagement is the dll which gives you access to the ActiveDirectory/LDAP. Since this is a Windows feature it will only work if you set your target framework in the project file to “net7.0-windows”. Also note that this means your plugin only runs under Windows. Obviously.
jhs
(-JHS-)
July 12, 2024, 10:59am
17
I tried that one too… with same results…
Returns this when trying to read UserPrinciples when CopyLocalLockFileAssemblies is set to false
Solution exception:Could not load file or assembly ‘System.DirectoryServices.AccountManagement, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. The system cannot find the file specified.
Returns this when loading components SolveInstance when CopyLocalLockFileAssemblies is set to true
Solution exception:System.DirectoryServices.AccountManagement is not supported on this platform.
Settings in project.cs file
<PropertyGroup>
<TargetFrameworks>net7.0-windows</TargetFrameworks>
<Version>1.0</Version>
<Title>UserPrincipleTest2</Title>
<Description>Description of UserPrincipleTest2</Description>
<TargetExt>.gha</TargetExt>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
File list when CopyLocalLockFileAssemblies is set to true
Can anyone test this if they can actually get this working? Very simple component…
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0-windows</TargetFrameworks>
<Version>1.0</Version>
<Title>UserPrincipleTest2</Title>
<Description>Description of UserPrincipleTest2</Description>
<TargetExt>.gha</TargetExt>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<Reference Include="GH_IO">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\GH_IO.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Grasshopper">
<HintPath>..\..\..\..\Program Files\Rhino 8\Plug-ins\Grasshopper\Grasshopper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RhinoCommon">
<HintPath>..\..\..\..\Program Files\Rhino 8\System\netcore\RhinoCommon.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
</Project>
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddBooleanParameter("Run", "Run", "True = the tool is running and waits for changes in \"Trigger Component\" input", GH_ParamAccess.item);
}
protected override void SolveInstance(IGH_DataAccess DA)
{
bool run = false;
if (!DA.GetData(0, ref run)) { return; }
if(!run) { return; }
//Checking if User Principle works ok
string userName = Environment.UserName;
string userFullName = UserPrincipal.Current.DisplayName;
}