我有这个类库被加载到第三方系统。我多年来一直使用自定义配置,并通过ConfigurationManager.OpenMappedExeConfiguration()访问它们,因为这总是允许我将配置文件与dll相关联,并避免必须修改第三方系统配置文件。我们目前正在升级系统,现在这不起作用。这个例外给我的印象是它通过在主持人exe位置开始探测程序集。我的组件存放在一个单独的位置,以避免我的所有东西与他们混合(更容易维护,因为我们有一组非常多样化的组件)。我发现通过将程序集及其配置放在exe的主安装目录中它确实有效,所以我认为绑定是这一天的问题,但就像我说我宁愿避免将我的所有内容复制到那个目录。这可能是关于如何将程序集加载到系统中的问题吗? ConfigurationManager的代码库是否有变化?那么远程访问配置文件的方法是什么呢?
我在他们的网站上发布了一个论坛问题,但我想在这里发布一些内容,以防有人知道.NET解决方法并不需要了解第三方系统API(AutoCAD 2015)。这是我得到的例外,它看起来像某种约束问题。也许他们已经改变了我们的程序集加载到系统的方式?他们做了几次安全性更改,所以我猜这是可能的。
发现了System.IO.FileNotFoundException _HResult = -2147024894 _message =无法加载文件或程序集' TestAutoCADApp,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其中一个依赖项。该系统找不到指定的文件。 的HResult = -2147024894 IsTransient = FALSE 消息=无法加载文件或程序集' TestAutoCADApp,版本= 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其中一个依赖项。该系统找不到指定的文件。 来源= System.Configuration FileName = TestAutoCADApp,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null
FusionLog ====预绑定状态信息=== 日志:DisplayName = TestAutoCADApp,版本= 1.0.0.0,Culture = neutral,PublicKeyToken = null (完全指定的) 日志:Appbase = file:/// C:/ Program Files / Autodesk / AutoCAD 2015 / 日志:初始PrivatePath = NULL
调用程序集:System.Configuration,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a。
日志:此绑定在默认加载上下文中启动。 日志:使用应用程序配置文件:C:\ Program Files \ Autodesk \ AutoCAD 2015 \ acad.exe.Config 日志:使用主机配置文件: 日志:使用C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ co nfig \ 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。
堆栈跟踪: at System.Configuration.TypeUtil.GetTypeWithReflectio nPermission(IInternalConfigHost host,String typeString,Boolean 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(String sectionGroupName) at TestAutoCADApp.Commands.TestConfigSettingsAccess(A ction`1 writeAction)在c:\ Development-TVA \ Visual Studio 2013 \ TestCode \ TestAutoCADApp \ TestAutoCADApp \ Comman ds.cs:第49行 的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;
答案 0 :(得分:2)
好吧,我终于从供应商那里听到了,结果发现他们曾经在他们的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一样,以便它可以读取和合并配置文件。它必须探测装配和失败。但这只是我的猜测。我不确定。无论哪种方式,实现此方法都会导致正确的程序集在失败时返回。