ASP.NET从bin文件夹加载非托管dll

时间:2010-05-25 17:57:00

标签: c# .net asp.net asp.net-mvc vb.net

问题:我在ASP.NET中使用嵌入式Firebird数据库。

现在,Firebird在本机dll周围有一个.NET包装器。

问题是,在ASP.NET编译和执行过程中,dll将阴影复制到临时文件夹。不幸的是,只有.NET dll,而不是本机dll。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms366723.aspx

现在,这使得必须将非托管dll放在system32目录(或路径环境变量中的任何其他目录)中。

现在,我想更改包装器/本机dll(opensource),因此如果它们只在bin文件夹中,它也会加载dll。

现在,我的问题是,我如何在.NET中从绝对路径加载非托管dll?
绝对路径是在运行时确定的,而不是在编译时确定的......

2 个答案:

答案 0 :(得分:4)

将原生dll嵌入到程序集中。

Application_Start()上,检查Environment.CurrentDirectoryAssembly.GetExecutingAssembly().Location或实际指向的位置,对于该文件,如果不存在,请通过Assembly.GetManifestResourceStream()将其流式传输出去

请注意,这可能会导致appdomain回收,例如重启你的应用程序,但由于你刚刚启动它,这不是问题。

不确定为什么要使用绝对路径,尤其是对于非托管dll。如果您只是将非托管dll放在与调用它的程序集相同的目录中,那么您将获得更好的里程,而不会感到痛苦。

答案 1 :(得分:2)

我遇到了类似的问题,但无论出于何种原因,在调用Application_Start()之前,绑定/加载都会失败。我的场景是我的Web服务引用了我自己的其他项目(Called Common),后者又引用了供应商的托管C ++ dll,后者又引用了非托管C ++ dll。供应商的托管C ++ dll未设置为“延迟加载”供应商的非托管dll。这意味着ASP.Net/Fusion尝试加载托管版本,它会立即失败。只是在我的bin文件夹中拥有供应商的托管dll会导致.Net尝试加载它并失败。

我的解决方案是......

  1. 创建一个POST构建事件,删除供应商的托管dll(非托管未按预期复制到我的bin)。这允许我的Web服务启动,但如果我尝试使用任何需要供应商的DLL的代码,它将失败。
  2. 右键单击Web服务,然后选择Add-> Existing item。浏览到两个供应商dll并选择“添加为链接”(单击“添加”按钮旁边的向下箭头)。
  3. 在两个新添加的供应商dll的属性选项卡中,使它们成为嵌入式资源。
  4. 现在,在Application_Start中,我通过Path.GetDirectoryName(Assembly.GetAssembly(typeof(ATypeInMyCommonLibrary)));找到我的公共库所在的目录。使用它作为我的输出路径,我将嵌入式dll从Assembly.GetExecutingAssembly().GetManifestResourceStream中拉出并写入通过FileStream
  5. 希望这有帮助!