Importing a dll via Import Library vs copying to packages folder + best practices for using third party libraries


#1

This question is actually two separate ones as stated in the topic but very related. So I thought posting them in one topic.

I have developed a Zerotouch library that is using a third party library. I have set the Copy Local property for the third party library to true (cause otherwise I get error messages on loading via Import Library). With this setting I can import my dll through Import Library command. And I get the nodes that are referencing the third party library and they work as expected. However, I get some nodes that are methods of the other referenced libraries such as Dynamo.Core and Dynamo.Graph (which I have also used). Also the UI nodes don’t load properly, which I think is an expected behaviour(?).

When I try loading my library as a package (and by that I mean creating the folders “bin”, “dyf”, “extra”, copying the pkg.json to the root folder and copying the dlls into the bin folder and opening Dynamo) the only nodes that load are the UI nodes which work fine. But other public methods which have referenced the third party dll don’t even load.

Could someone please explain this behaviour and provide the solution?

What I have tried so far was trying to delete the issue by embedding the third party dll into my own using ILMerge which didn’t get anywhere. Then I tried to add the third party dll as a resource which I then can load using GetManifestResourceStream() and the AppDomain.CurrentDomain.AssemblyResolve event. This also didn’t come to any help.


#2

This sounds strange.

Assemblies you do not use directly should not be loaded. You should only load your own assembly, which very well might be dependent on a "third party" assembly.

Assemblies you add but not load (via the pkg.json file) should not add anything inside Dynamo.

If you have used the ZeroTouch example from DynamoDS Github or build your own as that project, then you should not end into the problems you describe.

In my package do I have code (nodes) there is dependent on a COM object from an estimation software. This gives me no problem at all. You are welcome to dissect and investigate how my package is distributed and take a look into my pkg.json if that can help you.

Otherwise, will I suggest you to use DynamoDS Github for questions of this kind, most users at this forum are not coders, meaning you are dependent that some of us who code stumble upon a question as this.


#3

It’s very difficult with this type of question to tell you what is going on - for the most part Dynamo just relies on .net’s assembly loading mechanisms.

A minimal sample project that reproduces the issue is best:

If you have UI nodes and ZT nodes you should load your dlls in a package.

Your bin folder should include your dlls and your referenced dlls (which are not dynamo dlls - since those will already be loaded)

Please look in the dynamo console or debug dynamo with visual studio as it starts with normal CLR exceptions turned on - you will likely see a loading exception from .net with more info about what dll it cannot find or load with an error code that you can google: something like 0x8-----


#4

Thanks @erfajo for the input.

I have used the Dynamo Zerotouch Nuget package to setup my project in VS.

I’m not sure what is causing Dynamo to ignore those nodes which are dependent on my COM object. When adding your COM object as the reference what are the values for “Embed Interop Types” and “Isolated” properties in VS for that COM object?


#5

Well we can see that obviously two different loading procedure takes place with importing libraries through the Import Library command and importing libraries as a package. If we disregard the UI nodes difference, it appears that loading the dll as a package blocks some of the dependencies, while loading through Import Library doesn’t. Is that true?

With loading as a package, I have my referenced dlls in the bin folder. And when I debug with VS I get “Skipped loading symbols. Module is optimized and the debugger option ‘Just My Code’ is enabled” and if I uncheck the “Enable Just My Code” the referenced dll is “loaded” however the nodes that reference this dll aren’t loading in the library.

I’ll try putting together a sample project which reproduces the issue.


#6

when you use import library you instruct the VM to import that dll directly - package loading will attempt to load top level dlls which are marked as node-libraries in the package.json file- their dependencies will also be loaded by .net, but in most cases should not be imported into the VM as functions and classes.

I would avoid using embed introp types and just add the referenced dll to the bin folder.


#7

Also, please look in the Dynamo console for any errors loading your package - this thread reminds me of:

though it could be unrelated.

Also - did you enable CLR exceptions in the exceptions setting dialog? You will want to do this before dynamo starts loading your package.

When you say the dll is loaded, do you mean your zero touch dll, or the dll is depends on?

In the case of this thread the referenced dll was blocked on the machine and when manually copied to the bin folder was not loaded.(it was when it was loaded using copy local) I would investigate unblocking it - since you seem to have a similar symptoms (cause could be different of course).

If you provide a repro project I will check it out.


#8

image


#9

Also - did you enable CLR exceptions in the exceptions setting dialog? You will want to do this before dynamo starts loading your package.

I did enable all of them. Nothing really giving me any clue. I get the log as mentioned above.

When you say the dll is loaded, do you mean your zero touch dll, or the dll is depends on?

When “Just My Code” is enabled and I debug using the sandbox, ZT dll is loaded, and for the referenced dll I get “Skipped loading symbols. Module is optimized and the debugger option ‘Just My Code’ is enabled”. When “Just My Code” is disabled, both are loaded.

In the case of this thread the referenced dll was blocked on the machine and when manually copied to the bin folder was not loaded.(it was when it was loaded using copy local) I would investigate unblocking it - since you seem to have a similar symptoms (cause could be different of course).

Yeah that was my suspicion too. I copy the dlls in Dynamo Core packages folder using a post-build event. When I see their properties non of them are blocked. The other thing I also tested was the solution suggested here: http://thebuildingcoder.typepad.com/blog/2016/04/windows-10-security-blocks-external-command.html
The first solution which is adding the following to the revit.exe.config file and firing up Dynamo Revit instead of sandbox:

<runtime>
         <loadFromRemoteSources enabled="true"/>
</runtime>

That is also not making any change.

If you provide a repro project I will check it out.

Very basic but has the same issue. In this project I referenced Microsoft Word COM object and the properties are exactly the same as erfajo’s on the post above.


#10

@HossZamani a few things:

  • have you provided the word interop assemblies? I do not see them in the repo. ( if not - please provide instructions so I can use the same procedure you did for retrieving them/adding references/version etc.)
  • what version of dynamo/dynamo revit are you attempting to load this package with?

#11

If you have Word installed it must be here:

(The method which uses this reference should work with the older versions of Word, in case you have older versions installed.)

Once added I set the Copy Local property to true and Embed Interop Types & Isolated properties to false

Version of Dynamo is 1.3.2

Let me know if anything else needs clarifying. Thanks.


#12

Hi @HossZamani your package loads fine for me.

When I build your package it copies the binaries into the appData/Dynamo/DynamoCore/Packages folder - these packages are only loaded when DynamoSandbox starts, not when DynamoRevit starts - which version of dynamo are you starting?

If you’re trying to load this package in revit change your copy script to the dynamorevit packages folder.

If you have already done that - and you are sure your package is being loaded, then something else that revit has loaded is interfering with this dll from loading and you should remove other packages / addins until you find the culprit - you can also look in the modules window in visual studio to see if something else has loaded a different version of the COM library into revit’s process. In that case you may be able to do late binding and use whatever version is available instead of having a compile time dependency on a version that .net fails to load. (which will also make your package fail)

please also look in the dynamo console for any errors related to your package loading.


#13

Thanks Michael, your hints helped a lot in isolating the problem. But finally the culprit was the UI nodes that I had in my VS project. When I separated the UI nodes into another VS project, and put the resulting dll in the bin folder Dynamo loads everything fine.

I had no idea that UI nodes should be in a separate dll. So that was the big learning I had from this endeavour.