我有一个需要在ASP.NET WebApi操作的上下文中运行的C ++ / CLI DLL。
操作受ActionFilter影响,该操作使用log4net的LogicalThreadContext
来设置包含请求ID的属性;这很好地将请求ID写入日志条目。
问题是,当从C ++ / CLI dll加载类时,ASP.NET似乎正在创建一个appdomain。 (我似乎无法找到有关其工作方式的任何文档;我很乐意找到一些。)当appdomain管道尝试反序列化所有内容时,它会因为无法找到log4net.dll而窒息(见下面的堆栈跟踪)。
Fusion日志显示它正在查看C:\Windows\System32\inetsrv
,这是不正确的......我希望它可以查看探测路径或%PATH%
环境变量。
一些数据点:
bin
目录中提供,适用于我使用它的所有其他内容。log4net.LogicalThreadContext.Properties[...]
的来电,一切正常。bin
文件夹复制到C:\Windows\system32\inetsrv
,一切正常。<probing privatePath="bin"/>
元素指定探测路径。 Application_Start
中的global.asax.cs
方法将网络应用的bin
目录添加到%PATH%
环境变量:
var currentPathEnvVar = Environment.GetEnvironmentVariable("PATH");
var binPath = Path.Combine(Server.MapPath("~") ?? String.Empty, "bin");
_log.DebugFormat("Prepending paths to PATH: [{0}]", binPath);
Environment.SetEnvironmentVariable("PATH", String.Concat(binPath, Path.PathSeparator, currentPathEnvVar));
日志显示%PATH%
正在获得正确的前缀:
2015-06-05 17:07:48,816 1 DEBUG MyNamespace.WebApiApplication (null) Prepending paths to PATH: [C:\Program Files\MyCompany\MyApp\web\bin]
那么如何获得ASP.NET创建的appdomain以便在正确的位置查看加载程序集?
感谢。
这是所有这一切都失败时记录的堆栈跟踪。
2015-06-05 17:08:41,148 23 ERROR MyNamespace.MyController (null) Controller action failed
System.TypeInitializationException: The type initializer for '<Module>' threw an exception. ---> <CrtImplementationDetails>.ModuleLoadException: The C++ module failed to load while attempting to initialize the default appdomain.
---> System.Runtime.Serialization.SerializationException: Unable to find assembly 'log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a'.
Server stack trace:
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm)
at System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage.FixupForNewAppDomain()
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, SmuggledMethodReturnMessage& smuggledMrm)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[] args)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.AppDomain.IsDefaultAppDomain()
at <CrtImplementationDetails>.GetDefaultDomain() in f:\dd\vctools\crt\crtw32\h\minternal.h:line 367
at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr function, Void* cookie) in f:\dd\vctools\crt\crtw32\h\minternal.h:line 401
at <CrtImplementationDetails>.DefaultDomain.Initialize() in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 278
at <CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(LanguageSupport* ) in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 343
at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* ) in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 546
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 703
--- End of inner exception stack trace ---
at <CrtImplementationDetails>.ThrowModuleLoadException(String errorMessage, Exception innerException) in f:\dd\vctools\crt\crtw32\h\minternal.h:line 194
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* ) in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 713
at .cctor() in f:\dd\vctools\crt\crtw32\msilcrt\mstartup.cpp:line 754
--- End of inner exception stack trace ---
at MyNamespace.MyController.MyAction(String foo, Int64 bar, String baz)
答案 0 :(得分:0)
这帮助我解决了类似的问题: https://blogs.msdn.microsoft.com/jorman/2007/08/31/loading-c-assemblies-in-asp-net/ 面对选项2.a和建议的解决方案效果很好:
受保护的无效Application_Start(对象发送者,EventArgs e){ 字符串_path = String.Concat(System.Environment.GetEnvironmentVariable(“ PATH”),“;”, System.AppDomain.CurrentDomain.RelativeSearchPath); System.Environment.SetEnvironmentVariable(“ PATH”,_path,EnvironmentVariableTarget.Process); }