.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AutoCAD 2015 dll Configuration File Read Error

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
bjhuffine
1605 Views, 3 Replies

AutoCAD 2015 dll Configuration File Read Error

I've been using custom config files with my assemblies for some time now.  I like to keep the assemblies in separate folders so that I can manage our applications a little easier as we have a diverse set of them.  That means I typically just have to add the <loadFromRemoteSources enabled="true"/> to the <runtime> element in the acad.exe.config and I'm good to go.  To ensure my config is treated as being a part of the dll, I use reflection and the ConfigurationManager.OpenMappedExeConfiguration().  Now as I'm upgrading from AutoCAD 2012 to 2015, this no longer working.  Does anyone know why or have a solution as to working around it?  It still works if both the dll and its config are copied to the install directory, but I don't want to dump all our assemblies to the install directory to work around this.  This also screams that it has something to do with the assembly binding process and the exception with the fusion log data (using the sample code shown below) shows the following which looks typical for failed probing to me:

 

System.IO.FileNotFoundException was caught
  _HResult=-2147024894
  _message=Could not load file or assembly 'TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
  HResult=-2147024894
  IsTransient=false
  Message=Could not load file or assembly 'TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
  Source=System.Configuration
  FileName=TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
  FusionLog==== Pre-bind state information ===
LOG: DisplayName = TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/Autodesk/AutoCAD 2015/
LOG: Initial PrivatePath = NULL
Calling assembly : System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files\Autodesk\AutoCAD 2015\acad.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/AutoCAD 2015/TestAutoCADApp.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp/TestAutoCADApp.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp/TestAutoCADApp.EXE.

  StackTrace:
       at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
       at System.Configuration.MgmtConfigurationRecord.CreateSectionGroupFactory(FactoryRecord factoryRecord)
       at System.Configuration.MgmtConfigurationRecord.EnsureSectionGroupFactory(FactoryRecord factoryRecord)
       at System.Configuration.MgmtConfigurationRecord.GetSectionGroup(String configKey)
       at System.Configuration.Configuration.GetSectionGroup(String sectionGroupName)
       at TestAutoCADApp.Commands.TestConfigSettingsAccess(Action`1 writeAction) in c:\Development-TVA\Visual Studio 2013\TestCode\TestAutoCADApp\TestAutoCADApp\Commands.cs:line 49
  InnerException:

 

Here's a very generic example if you would like to replicate this yourself:

 

The command...

 

[CommandMethod("TestConfig")]
        public void TestConfig()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            TestConfigSettingsAccess(new Action<string>((string target) => ed.WriteMessage(target)));
        }

        public void TestConfigSettingsAccess(Action<string> writeAction)
        {
            try
            {
                TestAutoCADApp.Properties.Settings.Default.SamplePath = DateTime.Now.ToString();

                writeAction(TestAutoCADApp.Properties.Settings.Default.SamplePath);

                Uri uriCodeBase = new Uri(Assembly.GetExecutingAssembly().CodeBase);
                FileInfo appfilePath = new FileInfo(uriCodeBase.LocalPath + ".config");

                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = appfilePath.FullName;

                Configuration configuration = null;

                //Retrieve the Configuration file data and return
                configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

                MainGroup mainGroup = configuration.GetSectionGroup("mainGroup") as MainGroup;

                MainSection mainSection = mainGroup.Sections["mainSection"] as MainSection;

                SomeElement someElement = mainSection.SomeElement;

                writeAction(someElement.Name);
            }
            catch(SystemException ex)
            {
                //exception code
            }
        }

 

Here is the element, section, and group code:

 

    class MainGroup : ConfigurationSectionGroup
    {
        [ConfigurationProperty("mainSection", IsRequired = true, IsKey = false)]
        internal MainSection MainSection
        {
            get { return (MainSection)base.Sections["mainSection"]; }
        }
    }

 

    class MainSection : ConfigurationSection
    {
        [ConfigurationProperty("someElement", IsRequired = false, Options = ConfigurationPropertyOptions.None)]
        internal SomeElement SomeElement
        {
            get { return (SomeElement)this["someElement"]; }
            set { this["someElement"] = value; }
        }
    }

 

    class SomeElement : ConfigurationElement
    {
        private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();
        protected override ConfigurationPropertyCollection Properties
        {
            get { return _properties; }
        }
        private static ConfigurationProperty _name = new ConfigurationProperty("name", typeof(string), @"some name", null, null, ConfigurationPropertyOptions.IsRequired);
        internal string Name
        {
            get { return (string)base[_name]; }
            private set { base[_name] = value; }
        }

        public SomeElement()
        {
            this.Properties.Add(_name);
        }

    }

 

and now the configuration file (note the namespaces and the fully qualified assembly names need to be correct). You can ignore the <userSettings> element as I was playing around with that to see if it affected it any.

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="TestAutoCADApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
      <sectionGroup name="mainGroup"  type="TestAutoCADApp.MainGroup, TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <section name="mainSection" type="TestAutoCADApp.MainSection, TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </sectionGroup>
    </configSections>
    <userSettings>
        <TestAutoCADApp.Properties.Settings>
            <setting name="SamplePath" serializeAs="String">
                <value>C:\</value>
            </setting>
        </TestAutoCADApp.Properties.Settings>
    </userSettings>

  <mainGroup>
    <mainSection>
      <someElement name="Test from Custom Config"/>
    </mainSection>
  </mainGroup>
  

</configuration>

 

3 REPLIES 3
Message 2 of 4
moogalm
in reply to: bjhuffine

Hi ,

 

Can you please provide sample project to test at my end  ,I'm curious to investigate, I'm not sure  if this the similar problem we faced earlier where primary project is referring to some other references which are not available in acad install folder and causing assembly resolve issues.

 

http://adndevblog.typepad.com/autocad/Madhukar-Moogala/

 

 

Message 3 of 4
bjhuffine
in reply to: moogalm

Sure, no problem.  Attached is a project zipped.  I look forward to your response as this is making troubleshooting migration issues difficult.  I used VS 2013.

Message 4 of 4
moogalm
in reply to: bjhuffine

Hi , this the same issue I was talking to you earlier , you need to subscribe to assembly event and resolve by your self , autocad no longer resolves.

 

namespace CustomConfigIssue
{
    public class Commands
    {
        [CommandMethod("TestConfig")]
        public void TestConfig()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            TestConfigSettingsAccess(new Action<string>((string target) => ed.WriteMessage(target)));
        }

        public void TestConfigSettingsAccess(Action<string> writeAction)
        {

            /*
             * You need to hook to assembly resolve event
             * Autocad 2015 will not solve assemblies ,if assemblies are not in acad install folder
             * user need to subscribe to assembly loading event and send the assembly
             
             */
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            try
            {
                Uri uriCodeBase = new Uri(Assembly.GetExecutingAssembly().CodeBase);
                FileInfo appfilePath = new FileInfo(uriCodeBase.LocalPath + ".config");

                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = appfilePath.FullName;
                Configuration configuration = null;

                //Retrieve the Configuration file data and return
                configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

                MainGroup mainGroup = configuration.GetSectionGroup("mainGroup") as MainGroup;

                MainSection mainSection = mainGroup.Sections["mainSection"] as MainSection;

                SomeElement someElement = mainSection.SomeElement;

                writeAction(someElement.Name);
            }
            catch (SystemException ex)
            {
                //exception code
            }
        }

        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly assembly = null;
            Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
            String name;
            if (args.Name.IndexOf(",") > -1)
                name = args.Name.Substring(0, args.Name.IndexOf(","));
            else
                name = args.Name;

            foreach (Assembly assem in assems)
            {
                if(assem.GetName().Name == name)
                {
                    return assem;
                }
            }
           
                      

            return assembly;
        }
    }
}

 

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost