如何让IIS加载被WCF服务引用的本地DLL?

12

我有一个包含一些 C# 代码的 WCF 服务,它引用了一个 C++/CLI dll ,该dll又引用了一些本地 DLL 。我将所有必要的 DLL 放在我的 IIS 应用程序的 bin 文件夹中,但当 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自动被加载?


您的 web.config 文件的内容将有助于更好地理解它。 - Surjit Samra
1
没错,看起来没有任何问题。你的应用程序池启用了32位吗?你可以在IIS\应用程序池下找到你的应用程序池,然后选择你正在运行Web应用程序的一个。 - Surjit Samra
所有的DLL都是编译为x64,问题与此无关。当我将它们放在托管DLL所在的ASP.NET创建的位置旁边时,它们可以正常加载。我只需要ASP.NET从包含所有托管DLL的bin目录中拾取它们即可。 - Chris Marasti-Georg
1
@Surjit Samra 在意外清除我的暫存 ASP.NET 檔案目錄後,最後一個缺失的元素是在應用程序池上將啟用 32 位應用程序設置為 True。 我的項目編譯為 AnyCPU 平台且沒有足夠的權限來創建臨時目錄。 重新創建目錄並添加修改和寫入權限(快捷方式:啟用完全控制,然後禁用它)到我的IIS_IUSRS組,我的應用程序池能夠正常工作。 - Suncat2000
1个回答

10
可以在运行时设置 PATH 环境变量,以便 ASP.NET 进程可以找到 C++ DLL。您也可以在系统属性中全局设置此属性(环境变量 | PATH 属性)。以编程方式设置此属性不需要重新启动计算机。
  • Copy the required DLLs to one of the directories listed in the logic above.
  • 根据这篇文章,似乎本地的 DLL 需要在某些目录或路径上可用:

    这个问题的核心原因在于操作系统在运行时加载本地 DLL 的方式。本地 DLL 是使用以下逻辑加载的,但不包括“临时 ASP.NET 文件”和应用程序 /bin 文件夹。如果本地 DLL 没有与 .EXE 文件一起包含在 /bin 文件夹中,或者如果 DLL 不在 Path 环境变量中,则任何 .Net 应用程序都会出现此问题。

    1. 应用程序加载的目录。对于 ASP.Net,这将解析为 %windir%\Microsoft.Net\Framework\v###\ ,对于 IIS 6,这将解析为 %windir%\system32\inetsrv。
    2. 当前目录。对于 ASP.Net,这将解析为 %windir%\System32\inetsrv,对于内置 Web 服务器,这将解析为 C:\Program Files\Microsoft Visual Studio 8 下的路径。
    3. Windows 系统目录。使用 GetSystemDirectory 函数获取此目录的路径。
    4. Windows 目录。使用 GetWindowsDirectory 函数获取此目录的路径。
    5. 列在 PATH 环境变量中的目录。

    提供的解决方案如下:

    1. 使用 DLLImport 以相对或绝对路径在运行时加载 dll。
    2. 设置 PATH 环境变量,以便 ASP.Net 进程可以找到 C++ DLL。您可以在运行时设置此属性,以便仅影响运行代码的进程。您还可以在系统属性中全局设置此属性(环境变量 | PATH 属性)。以编程方式设置此属性不需要重新启动计算机。
    3. 将所需的 DLL 复制到上述逻辑中列出的目录之一。
    如果您想要进行ASP.Net应用程序的XCopy部署,可以将PATH指向Web应用程序的/bin文件夹。以下是从ASP.Net以编程方式设置路径的步骤。 与#2相关的一些更复杂的解决方案还涉及以编程方式更新PATH。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接