自定义配置部分:无法加载文件或程序集
我很难尝试访问配置文件中的自定义配置部分。
配置文件是从作为插件加载的 .dll 中读取的。我使用 配置部分设计器 VS 插件创建了配置和必要的代码。
命名空间是“ImportConfiguration”。 ConfigurationSection 类是“ImportWorkflows”。该程序集是 ImportEPDMAddin。
xml:
<configSections>
<section name="importWorkflows" type="ImportConfiguration.ImportWorkflows, ImportEPDMAddin"/>
</configSections>
每当我尝试读取配置时,都会收到错误:
为 importWorkflows 创建配置节处理程序时发生错误:无法加载文件或程序集“ImportEPDMAddin.dll”或其依赖项之一。系统找不到指定的文件。
该 dll 不会驻留在与可执行文件相同的目录中,因为加载插件的软件会将 dll 及其依赖项放置在它自己的目录中。 (我无法控制这一点。)
我将单例实例的代码编辑为以下内容:
string path = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
path = path.Replace("file:///", "");
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(path);
return configuration.GetSection(ImportWorkflowsSectionName) as ImportConfiguration.ImportWorkflows;
我也尝试使用简单的 NameValueFileSectionHandler ,但我收到一个异常,说它无法加载文件或程序集“系统” 。
我读过很多博客文章和文章,听起来好像可以读取 dll 的配置文件,但我就是无法让它工作。有什么想法吗?谢谢。
I'm having a very hard time trying to access a custom configuration section in my config file.
The config file is being read from a .dll that is loaded as a plug-in. I created the Configuration and necessary code using the Configuration Section Designer VS addin.
The namespace is 'ImportConfiguration'. The ConfigurationSection class is 'ImportWorkflows'. The assembly is ImportEPDMAddin.
The xml:
<configSections>
<section name="importWorkflows" type="ImportConfiguration.ImportWorkflows, ImportEPDMAddin"/>
</configSections>
Whenever I try to read in the config, I get the error:
An error occurred creating the configuration section handler for importWorkflows: Could not load file or assembly 'ImportEPDMAddin.dll' or one of its dependencies. The system cannot find the file specified.
The dll will not reside in the same directory as the executable as the software that loads the plugin places the dll and it's dependencies in it's own directory. (I can't control that.)
I edited the code for the singleton instance to the following:
string path = System.Reflection.Assembly.GetCallingAssembly().CodeBase;
path = path.Replace("file:///", "");
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(path);
return configuration.GetSection(ImportWorkflowsSectionName) as ImportConfiguration.ImportWorkflows;
I have also tried using a simple NameValueFileSectionHandler as well, but I get an exception saying that it can't load file or assembly 'System'.
I have read numerous blog posts and articles and it sounds like it is possible to read a config file in for a dll, but I just can't get it to work. Any ideas? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不幸的是,您需要将
ImportEPDMAddin
程序集驻留在与可执行文件相同的文件夹中,驻留在与您正在使用的 .Net 框架相关的 .Net Framework 文件夹中(即 C:\Windows \Microsoft.NET\Framework\v2.0.50727),或在全局程序集缓存中注册。唯一的其他选择是,如果您知道包含配置处理程序的定义类的程序集的路径,则可以在没有引用的情况下加载它,如下所示:
确保处理 AssemblyResolve 事件,因为如果没有它,这将引发异常。
Unfortunately, you will need to either have the
ImportEPDMAddin
assembly residing in the same folder as your executable, residing in the .Net framework folder related to the .Net framework you are using (i.e., C:\Windows\Microsoft.NET\Framework\v2.0.50727), or registered in the Global Assembly Cache.The only other option is, if you know the path to the assembly that contains the configuration handler's defining class, you can load it without a reference with something like this:
Make sure you handle the AssemblyResolve event, as this will throw an exception without it.
在主应用程序配置文件中,添加以下内容(其中插件是要从中加载程序集的文件夹。您可以使用分号分隔的多个路径。
取自 http://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.90%29。 ASPX
In your main applications config file, add the following (where plugins is the folder for your assembly to load from. You can use multiple paths semi-colon separated.
Taken from http://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.90%29.aspx
为了扩展 AJ 的出色答案,这里有一个自定义类,可以帮助减少注册和删除全局事件的开销。
我建议在 using 语句中创建一个实例,如下所示:
To expand on AJ's excellent answer, here is a custom class to assist with the overhead of registering and removing the global event.
I would suggest creating an instance in a using statement, like so:
你确定DLL首先被加载了吗?也许使用
Assembly.LoadFile("PATH")
?如果无法使 System.Configuration 中的类正常工作,您始终可以使用 XmlDocument 手动解析配置文件。使用 XPath 可以更轻松地获取数据。例如(假设上面的路径变量):
Have you made sure that DLL is loaded first? Perhaps with
Assembly.LoadFile("PATH")
?If you can't get the classes in System.Configuration to work properly, you can always fall back on using XmlDocument to manually parse the configuration file. Use XPaths to make getting the data easier. For example (assuming your path variable above):
您能否验证主机应用程序的配置文件中的探测路径是否设置正确?您当前的应用程序域中可能未加载所需的引用。
程序集绑定 -> 探测
Could you verify that the probing paths are setup correctly in your Host application's config file? It is possible that a needed reference is not being loaded in your current application domain.
Assembly Binding ->Probing
必须使用我的模块/插件程序集的完全限定类型字符串,该程序集位于探测目录中,以便可以找到它。以 EntityFramework 为例...
不正确:
正确
Had to use the fully qualified type string of my module/plugin assembly, which is in a probing directory, so it could be located. Using EntityFramework as an example...
Incorrect:
Correct
我尝试了 AJ 的答案和 rileywhite 的补充剂,但我发现这对我不起作用。
在我的场景中,自定义 ConfigurationSection 类已经在当前执行的程序集中,尝试加载它会导致堆栈溢出。我也不想将其放入 GAC,即使它确实解决了 OP 报告的问题。
最后,我发现这足以满足我的目的。也许其他人会发现它很有用:
I tried AJ's answer, with rileywhite's supplement but I found that did not work for me.
In my scenario, the custom ConfigurationSection class was already in the currently-executing assembly, and trying to load it causes a stack overflow. I also did not want to put it in GAC even though it did resolve the problem as reported by the OP.
In end, I found this to work well enough for my purpose. Maybe others will find it useful: