gpt4 book ai didi

c# - 从备用位置加载 log4net.dll

转载 作者:太空宇宙 更新时间:2023-11-03 13:38:52 25 4
gpt4 key购买 nike

我有一个自定义的 .Net dll 组件,它将通过 COM Interop 从 MS Access 调用。

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

由于部署问题,我们希望所有自定义代码都从单独的位置运行,而不是从 MS 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>

我使用 SysInternals procmon 确认在从 Access 调用组件时找到了 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:\mycomponent\alt.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)

最佳答案

我以前用过类似的东西。不过,有些注意事项:

  • 这是非常通用的,所以可以根据需要随意修改
  • 如果存在版本冲突(即主应用程序使用 log4net 2.0 而您的应用程序使用 log4net 3.0),您可能会弄乱 AppDomain

代码:

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。它的静态构造函数将处理维护

实例化代码后要做的第一件事:

new AssemblyResolver()

关于c# - 从备用位置加载 log4net.dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17817597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com