CSharp - 从备用位置加载 log4net.dll

  显示原文与译文双语对照的内容
0 0

我有一个自定义. NET dll组件,它将通过com互操作从 MS Access 调用。

因为 MSACCESS.EXE 是调用过程,所以默认情况下,它将在安装 MS Access的位置找到程序集。config文件和任何引用的ddl 。

由于部署考虑,我们希望所有定制代码从单独的位置运行,而不是从 Office 文件夹结构中运行。

我已经能够强制程序集从自定义位置加载它的配置信息,方法如下:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", customPath);
typeof(ConfigurationManager)
. GetField("s_initState", BindingFlags.NonPublic |
 BindingFlags.Static)
. SetValue(null, 0);
typeof(ConfigurationManager)
. GetField("s_configSystem", BindingFlags.NonPublic |
 BindingFlags.Static)
. SetValue(null, null);
typeof(ConfigurationManager)
. Assembly.GetTypes()
. Where(x => x.FullName ==
"System.Configuration.ClientConfigPaths")
. First()
. GetField("s_current", BindingFlags.NonPublic |
 BindingFlags.Static)
. SetValue(null, null);

似乎工作正常,除了日志记录之外,一切似乎都正常工作。 无论什么,log4net.dll 文件都不会从任何位于 MSACCESS.EXE 位置的位置加载。

我试图将以下内容添加到 app.config 文件( log4net.dll 与我的.NET 组件位于同一目录中) 中,但它似乎被忽略了。

<runtime>
 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 <probing privatePath="c:mycomponent"/>
 </assemblyBinding>
</runtime> 

当组件从Access调用时,我使用SysInternals确认dll正在被发现,并且成功地找到了它,但是它恢复到尝试从 MS Access 目录加载它,然后失败。

是否存在强制 log4net.dll 从我想要的位置加载?

以下是log4net内部调试日志的输出:

log4net:ERROR Failed to parse config file. Is the <configSections> specified as: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a"/>
System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for log4net: Could not load file or assembly 'log4net' or one of its dependencies. The system cannot find the file specified. (C:mycomponentalt.config line 4) ---> System.IO.FileNotFoundException: Could not load file or assembly 'log4net' or one of its dependencies. The system cannot find the file specified.
 at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
 at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.Init(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
 at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.InitWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord)
 at System.Configuration.RuntimeConfigurationRecord.CreateSectionFactory(FactoryRecord factoryRecord)
 at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
 --- End of inner exception stack trace ---
 at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
 at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
 at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
 at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
 at System.Configuration.ConfigurationManager.GetSection(String sectionName)
 at System.Configuration.ConfigurationSettings.GetConfig(String sectionName)
时间:原作者:4个回答

0 0

我以前用过这样的东西。 但是,有些注释:

  • 这是非常通用的,所以可以根据需要修改它
  • 如果存在冲突版本( IE ),则可能会搞乱 AppDomain 。 主应用程序使用 log4net 2.0,你的应用程序使用 log4net 3.0 )

代码:

class AssemblyResolver
 {
 static AssemblyResolver()
 {
 AppDomain.CurrentDomain.AssemblyResolve +=
 (sender, args) =>
 {
 var referencedAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
 var instanceName = referencedAssemblies.ToList().First(x => x.FullName == args.Name).Name;
 var loadFile = Assembly.LoadFile(System.IO.Path.GetDirectoryName(Assembly.GetAssembly(typeof(AssemblyResolver)).Location) + @"" + instanceName +".dll");
 return loadFile;
 }; 
 }
 public AssemblyResolver()
 {
 }
 }

然后,要使用这个,只需加载 AssemblyResolver 。 它的static 构造函数将处理维护

当你的代码被实例化时,首先要做的事情:

new AssemblyResolver()
原作者:
...