嵌入式非托管DLL不会在ASP.NET中加载

时间:2013-06-27 01:00:56

标签: asp.net wcf dll c++-cli unmanaged

我正在为一个WCF服务的ASP.NET主机工作。该服务引用C ++ / CLI包装器库,该库本身引用非托管DLL。基于this question我在ASP.NET DLL中嵌入了非托管DLL。然后我这样提取它:

string[] dlls = new [] { "myDLL.dll", "myDLLD.dll" };
Assembly assembly = Assembly.GetExecutingAssembly();
string location = Path.GetDirectoryName(assembly.Location);
Dictionary<string, Stream> streams =
    (from dll in dlls
    select new KeyValuePair<string, Stream>(
        dll, assembly.GetManifestResourceStream(typeof(Global), dll)))
    .ToDictionary(p => p.Key, p => p.Value);

foreach (KeyValuePair<string, Stream> stream in streams)
{
    using (FileStream file = new FileStream(Path.Combine(location, stream.Key),
                                            FileMode.Create))
    {
        stream.Value.CopyTo(file);
    }
}

我已尝试将此代码放在Application_Start()的{​​{1}}和Global.asax.cs AppInitialize()文件夹中,但在这两种情况下,我都会看到一个黄色的死亡屏幕在任一函数中命中断点之前,如何无法加载包装器DLL或其某个依赖项。我可以点击断点的唯一方法是将非托管DLL放在系统路径中的某个位置(例如App_Code),但这显然违背了嵌入DLL的目的。在ASP开始查看之前,我如何才能获得DLL所需的位置?

1 个答案:

答案 0 :(得分:2)

显然,ASP.NET的急切加载机制就是问题所在。因为托管包装器被复制到输出目录,所以ASP找到它并尝试在启动时链接到非托管DLL,即使它还没有存在。为了解决这个问题,我使用了C ++ / CLI DLL上的/DELAYLOAD链接器选项和Application_Start()中的LoadLibrary() P / Invoke以及上面显示的嵌入式DLL提取。