2

我正在为 WCF 服务开发 ASP.NET 主机。该服务引用一个 C++/CLI 包装库,该库本身引用一个非托管 DLL。基于这个问题,我在 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()Global.asax.cs,但在这两种情况下,我都会收到一个黄色死屏,说明在任一函数中遇到断点之前无法加载包装 DLL 或其依赖项之一。我可以打断点的唯一方法是将非托管 DLL 放置在系统路径中的某个位置(例如),但这显然违背了首先嵌入 DLL 的目的。在 ASP 开始查找之前,我如何才能将 DLL 放在需要的位置?AppInitialize()App_CodeC:\Windows\system

4

1 回答 1

2

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

于 2013-06-27T23:29:05.520 回答