我有一个包含一些 C# 代码的 WCF 服务,该代码引用了一个 C++/CLI dll,该 dll 引用了一些本机 DLL。我在 IIS 应用程序的 bin 文件夹中包含了所有必需的 DLL,但是当 IIS 加载托管 DLL 时,它似乎将它们复制到一个深层目录,例如:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\testwcf\73473be6\e625098c\assembly\dl3\aada7c33\85a7332b_2f9acc01
它将每个托管 DLL 复制到其自己的目录并加载它。当它到达我的 C++/CLI DLL 时,它会将其复制到如上所述的目录,然后无法加载依赖项。如果我手动将所有本机 DLL 复制到此文件夹中,它将运行,但这不是一个很好的解决方案。
我的 web.config 是 VS 创建的常用配置,其端点是根据 MSDN 文章定义的。
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="WcfService.Service1">
<endpoint address=""
binding="wsHttpBinding"
contract="WcfService.IService1" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
如何让这些DLL被自动拾取?
从这篇文章来看,似乎本机 DLL 需要在某些目录或路径中可用:
这个问题的核心原因在于操作系统的方式 在运行时加载本机 DLL。本机 DLL 使用以下方式加载 以下逻辑不包括临时 ASP.net 文件,也不包括 应用程序 /bin 文件夹。这个问题也会出现在任何.Net 如果本机 DLL 未包含在 /bin 文件夹中,则应用程序 .EXE 文件或者 DLL 不在路径环境变量中。
- 应用程序加载的目录。如果是 ASP.Net,这将解析为 %windir%\Microsoft.Net\Framework ###
或 %windir%\system32\inetsrv(对于 IIS 6)。- 当前目录。对于 ASP.Net,这将解析为 %windir%\System32\inetsrv 对于 IIS 6。如果使用内置 Web 服务器,则会解析为路径 在 C:\Program Files\Microsoft Visual Studio 8 下。
- Windows系统 目录。使用GetSystemDirectory函数获取系统路径 这个目录。
- Windows 目录。使用获取Windows目录 函数获取该目录的路径。
- 目录是 列在 PATH 环境变量中。
提供的解决方案如下:
- 使用 DLLImport 使用相对或绝对路径加载 dll 运行时。
- 设置 PATH 环境变量,以便 ASP.Net 进程可以 找到 C++ DLL。您可以在运行时设置此属性,以便 只影响运行代码的进程。你也可以这样设置 在系统属性中全局设置(环境变量 | PATH 财产)。以编程方式设置此项不需要重新启动 如果需要,您可以将 PATH 指向 Web 应用程序的 /bin 文件夹 能够对 ASP.Net 应用程序进行 XCopy 部署。这里 是从 ASP.Net 以编程方式设置路径的步骤。
还有一些与 #2 相关的更复杂的解决方案,其中涉及以编程方式更新 PATH。