• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009
    Accepted Solution

    Using AutoLoader with dependencies

    404 Views, 40 Replies
    01-08-2013 11:02 AM
    <?xml version="1.0" encoding="utf-8" ?>
    <ApplicationPackage SchemaVersion="1.0" AppVersion="1.0"
        ProductCode="{20F44DBA-0878-4ADE-91A4-E540E45A37FB}"
        Name="Menus"
    >
    
      <CompanyDetails
        Name="Automation Inc."
        Email="au@automation.com"
      />
    
      <Components>
        <RuntimeRequirements SupportPath=".\Contents\" SeriesMax="R19.0" SeriesMin="R19.0" Platform="AutoCAD*" OS="Win64"/> 
        <ComponentEntry ModuleName=".\Contents\Data.Mapping.dll" AppName="DelcoMapping" AppType="Dependency">
            <RuntimeRequirements SupportPath=".\Contents\" />
        </ComponentEntry>
        <ComponentEntry ModuleName=".\Contents\Menus.dll" AppName="Menus" AppType=".Net" LoadOnAutoCADStartup="True">
        </ComponentEntry>
      </Components>
    
    </ApplicationPackage>

     

    I set the support path, and even define the component entry to look for the Data.Mapping.dll in the contents folder.  This file exists there however everytime I start AutoCAD it says it cannot load file or assembly Data.Mapping.dll in the C:/Users/User/Documents/ folder

     

    So I am at a loss, how much more explicit can you get as to where this file is located in the packagecontents.xml???  Why does AutoCAD not read the file from the location which has been clearly specified? 

    Please use plain text.
    Member
    Posts: 4
    Registered: ‎01-23-2006

    Re: Using AutoLoader with dependencies

    01-08-2013 02:39 PM in reply to: tonofsteel
    You Maybe have a Problem with Windows using a different Path through localized imstall.
    Please use plain text.
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009

    Re: Using AutoLoader with dependencies

    01-17-2013 02:44 PM in reply to: tonofsteel

    Does anyone out there have any experience creating a bundle with multiple DLL's?  Has anyone else run into problems loading referenced DLL's?  I manually created the bundle and copied the files over, if I create an installer would this resolve locating dependencies?

    Please use plain text.
    Valued Mentor
    Posts: 299
    Registered: ‎05-06-2012

    Re: Using AutoLoader with dependencies

    01-20-2013 02:49 AM in reply to: tonofsteel

    tonofsteel wrote:
     

    I set the support path, and even define the component entry to look for the Data.Mapping.dll in the contents folder.  This file exists there however everytime I start AutoCAD it says it cannot load file or assembly Data.Mapping.dll in the C:/Users/User/Documents/ folder

     

    So I am at a loss, how much more explicit can you get as to where this file is located in the packagecontents.xml???  Why does AutoCAD not read the file from the location which has been clearly specified? 


    The error message you quoted is  'cannot load...'.

     

    'Cannot load' and cannot find/locate are not one and the same. It may be finding the assembly but the attempt to load it is failing due to a number of possible reasons, like a missing or bad dependent assembly/.DLL.

     

    Did you try NETLOADing the assembly from the same location? You should also try registering the assembly for demand loading at startup using the Applications key in the registry (e.g, the 'old way'), rather than using the AutoCAD plug-in loader.

     

    If using those methods work, then the problem is clearly in AutoCAD's plug-in loader.

     

     

    Please use plain text.
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009

    Re: Using AutoLoader with dependencies

    01-21-2013 07:39 AM in reply to: tonofsteel

    The error that I get is:

     

    MyPlugin.Initialize(): Could not load file or assembly 'file:///C:\Users\user\Documents\Data.Mapping.dll' or one of its dependencies.  The system cannot find the file specfied.

     

    This error is valid, this file is not in my documents folder.  My question is why is AutoCAD looking in that folder?  Especially because I have the following:

     

    <RuntimeRequirements SupportPath=".\Contents\"

     

    The contents has all of the .dll files in it including the main project .dll.  AutoCAD is finding this main file since it is getting to MyPlugin.Initialize() Even if I do not point to the dependency .dlls shouldn't AutoCAD automatically at the very least look in the same folder as the main .dll for its dependencies?

     

    Just in case that is not enough:

     

        <ComponentEntry ModuleName=".\Contents\Data.Mapping.dll" AppName="DMapping" AppType="Dependency">

     

    I have directly pointed out to AutoCAD where this file is located, so why would this exception be thrown before AutoCAD looks in the location I have pointed out?

     

    While developing I am compiling to debug, and when AutoCAD starts I Netload the main .dll file from the debug bin folder.  Since CopyLocal for all dependency .dlls is set to true they also are all in this same folder.  My application loads fine and everything runs.  I now want to deploy and that is how I got started with the bundles and the above problems.

     

    For testing I manually created the bundle folder structure, the XML file and copied the debug .dlls directly to the content folder.

     

    I am sure that this process is similar to what others might do when developing a plugin so what do you do differently when going from the Netload to the bundle?

     

    I notice as well in that trace that the error thrown includes:

    at System.Reflection.Assembly.LoadFrom(String assemblyFile)

     

    So would this be .Net looking for this file and not AutoCAD?  Other than what I have done in the XML file I do not know how to point to the correct file location.  It seems intuitive enough for me that when trying to load a dependency one of the default actions should be to look in the same folder as the assembly that is running.

     

    I will try the old method, but I would really like to know what piece I am missing here.

    Please use plain text.
    *Expert Elite*
    Posts: 1,639
    Registered: ‎04-29-2006

    Re: Using AutoLoader with dependencies

    01-21-2013 12:55 PM in reply to: tonofsteel

    Hi,

     

    Did you try with only one 'ComponentEntry' node for the main DLL ?

    Your app should find the Dependency dll while it's in a support path folder.

     

    <?xml version="1.0" encoding="utf-8" ?>
    <ApplicationPackage SchemaVersion="1.0" AppVersion="1.0" ProductCode="{20F44DBA-0878-4ADE-91A4-E540E45A37FB}" Name="Menus">
    
      <CompanyDetails Name="Automation Inc." Email="au@automation.com" />
    
      <Components>
        <RuntimeRequirements SupportPath=".\Contents\" SeriesMax="R19.0" SeriesMin="R19.0" Platform="AutoCAD*" OS="Win64"/> 
        <ComponentEntry ModuleName=".\Contents\Menus.dll" AppName="Menus" AppType=".Net" LoadOnAutoCADStartup="True">
        </ComponentEntry>
      </Components>
    
    </ApplicationPackage>

     

    Gilles Chanteau
    Please use plain text.
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009

    Re: Using AutoLoader with dependencies

    01-22-2013 02:25 PM in reply to: _gile

    I have tried this, the above post is what I arrived at after many iterations of trying to get this to work.  I do not understand what is going on here:

     

    <ComponentEntry ModuleName="./Contents/Data.Mapping.dll" AppType="Dependency" />

     

    Can anyone answer why it is looking for this file in my documents? 

     

    On another note I have tracked down this line in one of the libraries I am using:

     

    Assembly asm = Assembly.LoadFrom(MakeLoadReadyAssemblyName(mappingAssembly));

     

    And this line would be trying to load Data.Mapping.dll

     

    For some reason if I use netload to manually go to my dll in my bundle folder it loads and runs fine.  If I use the Autoloader then all of a sudden it wants to look in my documents for dependencies that are in the same folder as the executing assembly.  Something behind the scenes is not right here.

     

    So I guess I can use Autoloader to load my own Autoloader that runs netload to load my add-in? 

     

    Who would make the Autoloader work any different than Netload?

     

    Maybe I can modify the above Assembly.LoadFrom so that I somehow find the path of the currently executing assembly and then pre-pend this for a complete path?

     

    Something along the following?:

    string path;
    path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );

     Anyone have any experience with stuff like this?

     

     

    Please use plain text.
    Valued Mentor
    Posts: 299
    Registered: ‎05-06-2012

    Re: Using AutoLoader with dependencies

    01-22-2013 05:35 PM in reply to: _gile

    The problem is clearly in the Autodesk plug-in loader if your app loads without failure using NETLOAD.

     

    Here is one possible way of working around the issue:

     

    Handle the AppDomain.CurrentDomain.AssemblyResolve event. In handler for that event, when you see that it is looking for your Data.Mapping.dll assembly, use Assembly.LoadFrom() to load the assembly yourself (presuming you know where it is located or, you can find it), and then just return the Assembly object that's returned by Assembly.LoadFrom().

    Please use plain text.
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009

    Re: Using AutoLoader with dependencies

    01-23-2013 07:55 AM in reply to: tonofsteel

    The Assembly.LoadFrom documentation states the following:

     

    assemblyFile may be absolute or relative to the current directory, and the assembly is loaded into the domain of the caller.

     

    When I use the above code snippet I posted to get the path I fully expected it to somehow be pointing to my documents but when I run it the correct path for the bundle contents folder is shown.

     

    Thanks DiningPhilosopher I will have to try your suggestion next, it looks like there is a good chance that is what I will need to do to get this working.

    Please use plain text.
    Valued Contributor
    Posts: 78
    Registered: ‎12-04-2009

    Re: Using AutoLoader with dependencies

    01-23-2013 08:40 AM in reply to: tonofsteel

    I have added the following code:

     

    class MyPlugin : IExtensionApplication
    {
         public void Initialize()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

     

    And the event handler:

     

    Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        MessageBox.Show(args.RequestingAssembly.FullName + " requested: " + args.Name);

     

    And of course this event never happens and the code is never called.  I still get the same exception with the same path info and the same everything.

     

    If AutoCAD for some reason is handling this event would this cause my handler not to get called?

    Please use plain text.