How to manage assemblies in new C# editor?

The script for the custom goal relies on the KangarrooSolver.dll file but I don’t see the option ‘Manage Assemblies’ in the new editor.

@DanielPiker I tried Assembly.LoadFrom but I must be doing something wrong. How is this expected to work?

angle_sum_goal_mesh.gh (45.1 KB)

@martinsiegrist It’s all described on the notes in a new C# script (albeit not in Grasshopper :D)

// NOTE:
// - Reference to RhinoCommmod.dll is added by default
// - Use // r "<assembly name>" to reference other assemblies
//       e.g. // r "System.Text.Json"
//       e.g. // r "path/to/your/Library.dll"
// - Use // r nuget "<package name>==<package version>" to install and reference nuget packages.
//   >= and > are also accepted instead of ==
//       e.g. // r nuget "RestSharp==106.12.0"
//       e.g. // r nuget "RestSharp>=106.10.1"
// - Use #r "nuget: <package name>, <package version>" to install and reference nuget packages.
//       e.g. #r "nuget: RestSharp, 106.11.7"

Let me know if this makes sense

Thanks Ehsan. Works fine now. I’ll try to remember this…

1 Like

I was able to link to the KangarooSolver.dll file but now it seems I need to link to the Kangaroo2Components.gha file and so far this has failed. Path should be correct.

// r "C:\\Program Files\\Rhino 8 WIP\\Plug-ins\\Grasshopper\\Components\\Kangaroo2Component.gha"

using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

// using Kangaroo2Component;

/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
  /// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  /// <param name="text">String to print.</param>
  private void Print(string text) { /* Implementation hidden. */ }
  /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  /// <param name="format">String format.</param>
  /// <param name="args">Formatting parameters.</param>
  private void Print(string format, params object[] args) { /* Implementation hidden. */ }
  /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj) { /* Implementation hidden. */ }
  /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj, string method_name) { /* Implementation hidden. */ }
#endregion

#region Members
  /// <summary>Gets the current Rhino document.</summary>
  private readonly RhinoDoc RhinoDocument;
  /// <summary>Gets the Grasshopper document that owns this script.</summary>
  private readonly GH_Document GrasshopperDocument;
  /// <summary>Gets the Grasshopper script component that owns this script.</summary>
  private readonly IGH_Component Component;
  /// <summary>
  /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
  /// Any subsequent call within the same solution will increment the Iteration count.
  /// </summary>
  private readonly int Iteration;
#endregion

  /// <summary>
  /// This procedure contains the user code. Input parameters are provided as regular arguments,
  /// Output parameters as ref arguments. You don't have to assign output parameters,
  /// they will have a default value.
  /// </summary>
  private void RunScript(GeometryBase Geo, Polyline refPoly, Polyline targetInner, Polyline targetOuter, out object A)
  {

    SpaceMorph morph = new Kangaroo2Component.UtilityComponents.MorphToMesh.PolyPrism(refPoly, targetInner, targetOuter);
    GeometryBase geo2 = Geo.Duplicate();
    morph.Morph(geo2);
    A = geo2;
  }

  // <Custom additional code> 

  // </Custom additional code> 
}

meshmorphexample2.gh (30.6 KB)

1 Like

hi @martinsiegrist
i Renamed (‘‘.gha)it to(’’.dll) Kangaroo2Component.dll and it worked
Kangaroo2Component.zip (172.9 KB)

1 Like

Thanks @Rh-3d-p to me that seems like the script component needs a small tune up to accept *.gha as reference.

1 Like

Great. Added a YT ticket

RH-78079 Ensure C# scripts can reference binaries that do not have .dll extension

3 Likes

Thanks Ehsan this works fine now

1 Like

can you explain me it more clearly ?

It is explained at the top of an empty C# script. Let me know if this is not clear

// NOTE:
// - Reference to RhinoCommmod.dll is added by default
// - Use #r "nuget: <package name>, <package version>" to install and reference nuget packages.
//       e.g. #r "nuget: Rhino.Scripting, 0.7.0"
//       e.g. #r "nuget: RestSharp, 106.11.7"
// - Use #r "<assembly name>" to reference other assemblies
//       e.g. #r "System.Text.Json.dll"
//       e.g. #r "path/to/your/Library.dll"
//       e.g. #r "path/to/your/Plugin.gha"
1 Like

Hi, I’m looking into referenced assemblies in C# and wondering if there is intellisense/autocomplete being worked on? Right now it only prompts the scroll down for options within a particular dll after you start typing the first letter. For dummy coders like me it is really useful to see options after you hit the “.” in alphabetical order. This is working ok with internal RhinoCommon stuff but it would be really great to have for coding in the less documented plugins.

I tired following these directions and I’m having a bit of trouble installing the Newtonsoft.Json package. The #r “nuget: Newtonsoft.Json, 13.0.3” line works and I can debug / run the script but once I add the using lines below the script just stops working and the debuger won’t do anything.

Are there any system packages I might be able to use? This is a fairly straight forward component to parse a JSON string.

// Grasshopper Script Instance
region Usings
using System;

#r “nuget: Newtonsoft.Json, 13.0.3”
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
#endregion

public class Script_Instance
{
  // <Your other standard Grasshopper script code would appear here>

  /// <summary>
  /// This function will be called from the Grasshopper C# Script component.
  /// </summary>
  /// <param name="json">The raw JSON string input</param>
  /// <param name="path">The key path to look up (e.g. "key.nestedKey" or "key[2].someArray")</param>
  /// <param name="jsonValue">Resulting jsonValue found at the specified path</param>
  private void RunScript(string json, string path, ref object jsonValue)
  {
    // Basic sanity check
    if (string.IsNullOrWhiteSpace(json))
    {
      jsonValue = "Input JSON is empty or null.";
      return;
    }
    if (string.IsNullOrWhiteSpace(path))
    {
      jsonValue = "No path specified.";
      return;
    }

    try
    {
      // Parse the JSON string into a JToken (root node)
      JToken root = JToken.Parse(json);

      // Use SelectToken to navigate using the path
      // e.g. "person.name" or "items[3].price"
      JToken token = root.SelectToken(path);

      // If token is null, that means the path didn't resolve
      if (token == null)
      {
        jsonValue = $"No jsonValue found at path: {path}";
      }
      else
      {
        // Convert the token to its string representation
        jsonValue = token.ToString();
      }
    }
    catch (Exception ex)
    {
      // If anything fails (e.g., invalid JSON or invalid path), output the error message
      jsonValue = $"Error: {ex.Message}";
    }
  }
}

Seems like the .Linq extension on a loaded package produces some problems. I removed that but now it seems that the namespace is not being recognized or the package is not actually getting loaded?