Victor Chekalin
Victor Chekalin

Reputation: 776

Problems with load assembly

I'm writing Add-In for the application. AddIn is a Dll and it is located in the specific folder %APPDATA&/Application/AddIns/MyAddIn

So, I have a solution with several projects and the MyAddInFolder contains following files:

IVC.Common.dll 
IVC.MaterialCatalogEditorAddIn.dll
IVC.MaterialCatalogEditor.dll

The application calls method located in the IVC.MaterialCatalogEditorAddIn.dll and IVC.MaterialCatalogEditorAddIn.dll referenced to the IVC.MaterialCatalogEditor.dll and the IVC.MaterialCatalogEditor.dll referenced to the IVC.Common.dll

There is a WPF froms in the IVC.MaterialCatalogEditor.dll. And on of the xaml file is referenced to the IVC.Common.dll

When I try to execute AddIn command from the application I get an exception "Could not load assembly IVC.Common.dll"

I used FusionLogViewer and I got the following message logs

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files\Autodesk\Revit Structure 2012\Program\Revit.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = SK\ChekalinVV
LOG: DisplayName = IVC.MaterialCatalogEditor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Revit.exe
Calling assembly : IVC.MaterialCatalogEditorAddIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Program Files\Autodesk\Revit Structure 2012\Program\Revit.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.MaterialCatalogEditor.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.MaterialCatalogEditor/IVC.MaterialCatalogEditor.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.MaterialCatalogEditor.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.MaterialCatalogEditor/IVC.MaterialCatalogEditor.EXE.
LOG: Attempting download of new URL file:///C:/Users/ChekalinVV/AppData/Roaming/Autodesk/Revit/Addins/2012/IVC/FamilyManager/IVC.MaterialCatalogEditor.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\ChekalinVV\AppData\Roaming\Autodesk\Revit\Addins\2012\IVC\FamilyManager\IVC.MaterialCatalogEditor.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: IVC.MaterialCatalogEditor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
LOG: Where-ref bind Codebase does not match what is found in default context. Keep the result in LoadFrom context.
LOG: Binding succeeds. Returns assembly from C:\Users\ChekalinVV\AppData\Roaming\Autodesk\Revit\Addins\2012\IVC\FamilyManager\IVC.MaterialCatalogEditor.dll.
LOG: Assembly is loaded in LoadFrom load context.

Here is everything ok. The IVC.MaterialCatalogEditorAddIn.dll calls *IVC.MaterialCatalogEditor.dll*in the AddIn folder

But the next log:

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files\Autodesk\Revit Structure 2012\Program\Revit.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = SK\ChekalinVV
LOG: DisplayName = IVC.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Revit.exe
Calling assembly : PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files\Autodesk\Revit Structure 2012\Program\Revit.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.Common.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.Common/IVC.Common.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.Common.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/Revit Structure 2012/Program/IVC.Common/IVC.Common.EXE.
LOG: All probing URLs attempted and failed.

The PresebtationFramework assembly try called the IVC.Common.dll and try loaded only from application folder.

Why the one dll is trying loaded from the AddIn folder, but another dll is trying loaded from application folder only? And how to solve my problem.

All project has Any CPU Platform target. The application is x64.

When I load IVC.MaterialCatalogEditor.dll from the test executable application everythings work fine.

EDITED Some code:

The main code in the IVC.MaterialCatalogEditorAddIn.dll

[Transaction(TransactionMode.ReadOnly)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {            

            MaterialsWindow materialsWindow =
                new MaterialsWindow();
            materialsWindow.DataContext = 
                new MaterialsViewModel();

            materialsWindow.ShowDialog();

            return Result.Succeeded;
        }
    }

The MaterialsWindow class and the MaterialsViewModel class are located in the IVC.MaterialCatalogEditor.dll

The debbuger show error on this part of xaml in the IVC.MaterialCatalogEditor.dll:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                    
                    xmlns:ViewModel="clr-namespace:IVC.MaterialCatalogEditor.ViewModel"
                    xmlns:Common="clr-namespace:IVC.Common;assembly=IVC.Common">
<DataTemplate
            DataType="{x:Type Common:ResourceWithCharge}">
<!-- Some data template -->
</DataTemplate>
</ResourceDictionary>

EDITED 2 I've written the test solution with the same structure as in the my working solution. It is works without any errors when I launch it from the test application. But if I execute it from the AddIn it fails with "Could not load assembly Common.dll"

Test Solution

Upvotes: 0

Views: 5301

Answers (2)

Maxence
Maxence

Reputation: 13306

This is because IVC.Common.dll is loaded with Assembly.Load() by WPF in the default context when the compiled XAML (BAML) is loaded.

You should try to edit Revit.exe.config this way:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>  
     <assemblyIdentity name="IVC.Common" />  
       <codeBase href="<Not sure how you can put %APPDATA% here>\Application\AddIns\MyAddIn\IVC.Common.dll"/>  
     </dependentAssembly>  
  </assemblyBinding>
</runtime>

Upvotes: 0

Alexander Efimov
Alexander Efimov

Reputation: 2687

While assembly probing fails you have a couple of ways to go:

  1. Change assembly binding using app.config file
  2. Handle Assembly loading failure by attaching to AssemblyResolve of current app domain and load necessary assemblies using c# code.

Upvotes: 1

Related Questions