tmakin / RhinoCommonUnitTesting

Example of unit testing RhinoCommon from within the Visual Studio test runner on windows
35 stars 14 forks source link

Updating RhinoCommon/Grasshopper to v7 causes System.IO.FileNotFoundException #3

Open clicketyclackety opened 3 years ago

clicketyclackety commented 3 years ago

If I clone the project freshly and upgrade from the existing versions of GH/Rhino to the latest pre-release, The GHBox_Centroid_ReturnsGHPoint Test will return the following error:

System.IO.FileNotFoundException : Could not load file or assembly 'Grasshopper, Version=7.0.20168.13070, Culture=neutral, PublicKeyToken=dda4f5ec2cd80803' or one of its dependencies. The system cannot find the file specified. Stack Trace: XunitExampleTests.GHBox_Centroid_ReturnsGHPoint()

I've checked my local .nuget folder and this has the package in. I have no other issues with other projects using this package.

clicketyclackety commented 3 years ago

I have found in my code that I have had to explicitly add the Grasshopper Directory in the XunitTestInitFixture.cs file, this then loads perfectly.


public class XunitTestInitFixture : IDisposable
{
    static bool initialized = false;
    static string systemDir = null;
    static string systemDirOld = null;
    static string ghSystemDir = null;

    public XunitTestInitFixture()
    {
        ////Check if the fixture is already initialised
        if (initialized)
        {
            throw new InvalidOperationException("AssemblyInitialize should only be called once");
        }
        initialized = true;

        // Make surte we are running the tests as 64x
        Assert.True(Environment.Is64BitProcess, "Tests must be run as x64");

        // Set path to rhino system directory
        string envPath = Environment.GetEnvironmentVariable("path");
        string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
        systemDir = System.IO.Path.Combine(programFiles, "Rhino 7 WIP", "System");
        systemDirOld = System.IO.Path.Combine(programFiles, "Rhino WIP", "System");
        if (System.IO.Directory.Exists(systemDir) != true)
        {
            systemDir = systemDirOld;
        }

        ghSystemDir = System.IO.Path.Combine(programFiles, "Rhino 7 WIP", "Plug-ins", "Grasshopper");

        Assert.True(System.IO.Directory.Exists(systemDir), string.Format("Rhino system dir not found: {0}", systemDir));
        Assert.True(System.IO.Directory.Exists(systemDir), string.Format("Rhino system dir not found: {0}", systemDir));
        Assert.True(System.IO.Directory.Exists(ghSystemDir), string.Format("Grasshopper system dir not found: {0}", ghSystemDir));

        // Add rhino system directory to path (for RhinoLibrary.dll)
        Environment.SetEnvironmentVariable("path", envPath + ";" + systemDir + ";" + ghSystemDir);

        // Add hook for .Net assmbly resolve (for RhinoCommmon.dll)
        AppDomain.CurrentDomain.AssemblyResolve += ResolveRhinoCommon;

        // Start headless Rhino process
        LaunchInProcess(0, 0);
    }

    private static Assembly ResolveRhinoCommon(object sender, ResolveEventArgs args)
    {
        var name = args.Name;

        if (name.StartsWith("RhinoCommon"))
        {
            var path = System.IO.Path.Combine(systemDir, "RhinoCommon.dll");
            return Assembly.LoadFrom(path);
        }
        if (name.StartsWith("Grasshopper"))
        {
            var path = System.IO.Path.Combine(ghSystemDir, "Grasshopper.dll");
            return Assembly.LoadFrom(path);
        }

        return null;
    }

    public void Dispose()
    {
        //Cleaning up
        ExitInProcess();
        //initialized = false;
    }

    [DllImport("RhinoLibrary.dll")]
    internal static extern int LaunchInProcess(int reserved1, int reserved2);

    [DllImport("RhinoLibrary.dll")]
    internal static extern int ExitInProcess();

}
tmakin commented 3 years ago

@clicketyclackety Sorry, this repo has not had much attention recently! But I've just merged a PR that adds support for Rhino 7, so please check that out and let me know if you still have any issues.