c# - Load log4net.dll from alternate location -
i have custom .net dll component called ms access via com interop.
because msaccess.exe calling process, default attempt locate assemblies .config file, , referenced ddls, @ location ms access installed.
because of deployment concerns, want of custom code run separate location, not within ms office folder structure.
i've been able force assembly load it's configuration information custom location using:
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);
that seems work fine , seems work @ point except logging. no matter what, log4net.dll file not load location other directory msaccess.exe located.
i tried adding following app.config file (log4net.dll in same directory .net component) seems ignored.
<runtime> <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatepath="c:\mycomponent" /> </assemblybinding> </runtime>
i used sysinternals procmon confirm dll being found when component called access, , located, reverts trying load ms access directory , fails.
is there anyway force log4net.dll load location want?
here's output log4net internal debug log:
log4net:error failed parse config file. <configsections> specified as: <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler,log4net, version=1.2.11.0, culture=neutral, publickeytoken=669e0ddf0bb1aa2a" /> system.configuration.configurationerrorsexception: error occurred creating configuration section handler log4net: not load file or assembly 'log4net' or 1 of dependencies. system cannot find file specified. (c:\mycomponent\alt.config line 4) ---> system.io.filenotfoundexception: not load file or assembly 'log4net' or 1 of dependencies. system cannot find file specified. @ system.configuration.typeutil.gettypewithreflectionpermission(iinternalconfighost host, string typestring, boolean throwonerror) @ system.configuration.runtimeconfigurationrecord.runtimeconfigurationfactory.init(runtimeconfigurationrecord configrecord, factoryrecord factoryrecord) @ system.configuration.runtimeconfigurationrecord.runtimeconfigurationfactory.initwithrestrictedpermissions(runtimeconfigurationrecord configrecord, factoryrecord factoryrecord) @ system.configuration.runtimeconfigurationrecord.createsectionfactory(factoryrecord factoryrecord) @ system.configuration.baseconfigurationrecord.findandensurefactoryrecord(string configkey, boolean& isrootdeclaredhere) --- end of inner exception stack trace --- @ system.configuration.baseconfigurationrecord.findandensurefactoryrecord(string configkey, boolean& isrootdeclaredhere) @ system.configuration.baseconfigurationrecord.getsectionrecursive(string configkey, boolean getlkg, boolean checkpermission, boolean getruntimeobject, boolean requestishere, object& result, object& resultruntimeobject) @ system.configuration.baseconfigurationrecord.getsection(string configkey) @ system.configuration.clientconfigurationsystem.system.configuration.internal.iinternalconfigsystem.getsection(string sectionname) @ system.configuration.configurationmanager.getsection(string sectionname) @ system.configuration.configurationsettings.getconfig(string sectionname)
i have used before. notes, though:
- this pretty generic, feel free modify needed
- you can potentially mess appdomain if there conflicting versions (ie. main app uses log4net 2.0 , app uses log4net 3.0)
code:
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() { } }
then, use this, load assemblyresolver
. static constructor deal maintenance
first thing when code instantiated:
new assemblyresolver()
Comments
Post a Comment