我有被加载到第三方系统中的此类库。这些年来,我一直使用自定义配置,并通过ConfigurationManager.OpenMappedExeConfiguration()访​​问它们,因为这始终使我能够将配置文件与dll关联起来,而不必修改第三方系统配置文件。我们目前正在升级系统,现在不起作用。异常给我的印象是,它是从主机exe的位置开始进行程序集的探测。我的程序集存储在一个单独的位置,以避免将我的所有东西与它们的内容混合在一起(因为我们有非常多种多样的程序集,因此维护更加简便)。我发现通过将程序集及其配置放置在exe的主安装目录中即可正常工作,因此我认为绑定已成为当今的问题,但就像我说的那样,我宁愿避免将所有内容复制到该目录中。这可能是关于程序集如何加载到系统中的问题吗? ConfigurationManager的代码库是否进行了更改?那么,远程访问配置文件的更简单的方法是什么?

我已经在他们的网站上发布了一个论坛问题,但我想在这里发布一些内容,以防万一有人意识到某个.NET解决方法不需要第三方系统API的知识(AutoCAD 2015)。这是我遇到的异常,在我看来这是某种绑定问题。也许他们改变了将程序集加载到系统中的方式?他们进行了几次安全更改,所以我想这是可能的。


  捕获了System.IO.FileNotFoundException
    _HResult = -2147024894
    _message =无法加载文件或程序集“ TestAutoCADApp,版本= 1.0.0.0,区域性=中性,PublicKeyToken =空”或其依赖项之一。该系统找不到指定的文件。
    HResult = -2147024894
    IsTransient =假
    消息=无法加载文件或程序集'TestAutoCADApp,版本= 1.0.0.0,区域性=中性,公共密钥令牌=空'或其依赖项之一。该系统找不到指定的文件。
    源= System.Configuration
    FileName = TestAutoCADApp,版本= 1.0.0.0,文化=中性,PublicKeyToken =空
  
  FusionLog ====预绑定状态信息===
  日志:DisplayName = TestAutoCADApp,版本= 1.0.0.0,文化=中性,PublicKeyToken =空
   (完全指定)
  日志:Appbase = file:/// C:/ Program Files / Autodesk / AutoCAD 2015 /
  日志:初始PrivatePath = NULL
  
  调用程序集:System.Configuration,版本= 4.0.0.0,区域性=中性,PublicKeyToken = b03f5f7f11d50a3a。
  
  日志:此绑定在默认的加载上下文中开始。
  日志:使用应用程序配置文件:C:\ Program Files \ Autodesk \ AutoCAD 2015 \ acad.exe.Config
  日志:使用主机配置文件:
  日志:使用C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ config \ machine.config中的计算机配置文件。
  日志:目前未将策略应用于引用(私有,自定义,部分或基于位置的程序集绑定)。
  日志:尝试下载新的URL文件:/// C:/ Program Files / Autodesk / AutoCAD 2015 / TestAutoCADApp.DLL。
  日志:尝试下载新的URL文件:/// C:/ Program Files / Autodesk / AutoCAD 2015 / TestAutoCADApp / TestAutoCADApp.DLL。
  日志:尝试下载新的URL文件:/// C:/ Program Files / Autodesk / AutoCAD 2015 / TestAutoCADApp.EXE。
  日志:尝试下载新的URL文件:/// C:/ Program Files / Autodesk / AutoCAD 2015 / TestAutoCADApp / TestAutoCADApp.EXE。
  
  堆栈跟踪:
         在System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost主机,字符串typeString,布尔throwOnError)
         在System.Configuration.MgmtConfigurationRecord.Creat \ eSectionGroupFactory(FactoryRecord factoryRecord)
         在System.Configuration.MgmtConfigurationRecord.Ensur.eSectionGroupFactory(FactoryRecord factoryRecord)
         在System.Configuration.MgmtConfigurationRecord.GetSe ctionGroup(String configKey)
         在System.Configuration.Configuration.GetSectionGroup(字符串sectionGroupName)
         在c:\ Development-TVA \ Visual Studio 2013 \ TestCode \ TestAutoCADApp \ TestAutoCADApp \ Commands.cs:第49行中的TestAutoCADApp.Commands.TestConfigSettingsAccess(Action 1 writeAction)中
    InnerException:


我可以显示自定义配置代码,但是如果您对系统不熟悉,那么它对您没有任何好处。因此,现在,这是一个非常普通的示例,说明了我如何访问它,这已经有一段时间了。

  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;

最佳答案

好吧,我终于从供应商那里收到消息,事实证明他们曾经在其API中处理AssemblyResolve事件,该事件恰好解决了在加载主DLL时出现问题的情况下加载次级DLL的问题。他们显然对此有疑问,因此决定在最新版本中删除它。他们建议我自己注册该事件并使用以下代码(对于对此问题也感兴趣的人)以解决此问题。

在原始问题所示的代码中,在开头添加:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;


和事件代表:

    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;
    }


我希望这样做比它有意义,但是我猜想ConfigurationManager必须尝试访问dll,就好像它是辅助dll一样,以便它可以读取和合并配置文件。它必须正在探测组装是否失败。但这只是我的猜测。我不确定无论哪种方式,实施此方法都将导致失败时返回正确的程序集。

关于c# - ConfigurationManager.OpenMappedExeConfiguration的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27401841/

10-12 02:55