从 Asp.Net 应用程序加载第三方 dll 时出错
情况相当复杂(我的英语非常基础),但让我们尝试解释一下:
我正在开发一个 Asp.net Web 服务,从外部 dll 调用方法。
该外部 dll 调用其他 .net dll 中的某些方法。
所以我们有:
Asp.net WS ----> External.dll ----> other.NEt.Dll(---> other .netdll)
您必须知道外部 dll 使用路径(由初始化方法给出)来解析其内部引用。
总之,我有一个Web应用程序,其中添加了对External.dll的引用和完全受信任的路径( c:\EXTERNAL ),其中包含external.dll所需的所有.net dll。
环顾四周,我找到了要添加到 application_START 的代码:
Dim path As String = String.Concat(System.Environment.GetEnvironmentVariable("PATH"), ";", "c:\EXTERNAL)
System.Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Machine)
这将我的 c:\EXTERNAL 添加到全局环境路径。
通过从 Visual Studio 开发服务器运行此配置,我没有收到任何错误,并且一切正常。
当我在本地 IIS 服务器上发布应用程序时,出现各种错误: 起初,结果是这样的:
Failure reading <Myobject> control of <(static)> type
Unable to create <myobject> object (<C:\(WRONGPATH)\needed.net.dll> assembly)
为了解决这个问题,我尝试将所需的 .net dll 添加到 wwwroot 中我的应用程序的 /bin 中,但结果是这样的:
Failure reading <MyType> control of <Myobject> type
Error returned by .NET Framework:
System.ArgumentException: Un oggetto di tipo 'ComNet.BaseControl.LoginDisplayLayout' non può essere convertito nel tipo 'ComNet.BaseControl.LoginDisplayLayout'.
in System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
in System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
in CDotNetType.bSetProperty(CDotNetType* , Object gcrObj, SByte* pszNom, CSLevel* pclPile, Int32 nDimension, Int32* pnTabDimension, STOperationDotNet* pstOperation)
这次看起来它正在加载相同的 dll,但从位置不同,造成冲突。
现在就这样了。我很难解释这个 dll 地狱,但基本上我想复制当应用程序在 Visual Studio 开发服务器中运行良好时发生的情况。 我还读到,IIS 在不重新启动的情况下无法解析添加的 PATH,因此我尝试将 c:\external 手动添加到 PATH 并重新启动,但出现相同的错误。
感谢您的阅读,希望有人能提供帮助。
(抱歉语法或拼写错误!(我是意大利人..))
尼古拉
the situation is quite complex ( and my english very basic) but let's try to explain:
i'm developing a Asp.net web service calling a method from an external dll.
This external dll calls some method from other .net dlls.
So we have:
Asp.net WS ----> External.dll ----> other.NEt.Dll(---> other .netdll)
You have to know that the external dll uses a path ( given by an initialize method) to resolve its internal reference.
In conclusion i have a web application with an added reference to my External.dll and a fully trusted path ( c:\EXTERNAL ) full of all the .net dlls needed by external.dll.
Looking around i've found this code to add to the application_START:
Dim path As String = String.Concat(System.Environment.GetEnvironmentVariable("PATH"), ";", "c:\EXTERNAL)
System.Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Machine)
this add my c:\EXTERNAL to global environment PATH.
With this configuration running from the Visual Studio development server i get no error and it all works correctly.
When i publish the application on my local IIS server it gives various errors:
At first the result is something like:
Failure reading <Myobject> control of <(static)> type
Unable to create <myobject> object (<C:\(WRONGPATH)\needed.net.dll> assembly)
To resolve this i've tried to add the needed .net dlls to the /bin of my application in wwwroot but the result is something like:
Failure reading <MyType> control of <Myobject> type
Error returned by .NET Framework:
System.ArgumentException: Un oggetto di tipo 'ComNet.BaseControl.LoginDisplayLayout' non può essere convertito nel tipo 'ComNet.BaseControl.LoginDisplayLayout'.
in System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
in System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
in System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
in CDotNetType.bSetProperty(CDotNetType* , Object gcrObj, SByte* pszNom, CSLevel* pclPile, Int32 nDimension, Int32* pnTabDimension, STOperationDotNet* pstOperation)
this time it looks like it's loading the same dll but from different location causing conflicts.
Now that's all. Its hard for me to explain this dll-hell but basically i would like to replicate whats happening when the application works well in the visual studio development server.
I've also read that IIS does not resolve Added PATH without rebooting so i tried to add c:\external manually to the PATH and reboot but same errors appears.
Thank you for reading, i hope someone can help.
( sorry for grammar or spelling errors! ( i'm italian..))
Nicola
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试将所有外部 .NET dll 放入网站的 bin 目录中。
当您在 Visual Studio 中将引用添加到单独的库或项目时,它通常会将 DLL 从该项目复制到网站的 BIN 目录中,但它并不总是获取该项目所依赖的 DLL 文件。
所以如果:yourwebsite.dll -->助手.dll --> helperComponent.dll --> widget.dll(其中 --> 是引用),当您构建时,只有 helper.dll 最终与 yourwebsite.dll 一起出现在 bin 目录中。您通常希望将它们全部放在同一个地方。那么你就不必担心你的道路或任何其他事情。
或者,如果所有这些程序集都是强命名的,您可以使用 gacutil 将它们添加到全局程序集缓存中,并通过其标识符而不是文件来引用它们。
这是一本关于项目组织的很好的读物。 “复制本地”部分就涉及到这一点。您可以在构建后事件中设置 xcopy,将这些第二级和第三级引用放入解决方案文件下方的 bin 目录中。
http://www.simple-talk.com/dotnet/.net-framework/partitioning-your-code-base-through-.net-assemblies-and-visual-studio-projects/
Try dropping all of the external .NET dll's into the bin directory of your website.
When you add a reference in Visual Studio to a separate library or project, it will generally copy the DLL's from that project into your web site's BIN directory, but it won't always grab the DLL files that that project depends on.
So if: yourwebsite.dll --> helper.dll --> helperComponent.dll --> widget.dll (where --> is a reference), when you build only helper.dll ends up in the bin directory alongside yourwebsite.dll. You generally want to get all of them in the same place. Then you shouldn't have to worry about your path or any of that stuff.
Alternatively, if all of those assemblies are strongly named, you can add them to the global assembly cache using gacutil and reference them by their identifier instead of the file.
This was a pretty good read about project organization. The section on 'Copy Local' plays into this. You can setup an xcopy in your Post Build events to put those 2nd and 3rd level references in the bin directory below your solution file.
http://www.simple-talk.com/dotnet/.net-framework/partitioning-your-code-base-through-.net-assemblies-and-visual-studio-projects/