Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get IIS to load a native DLL referenced by my WCF service?

Tags:

c++

iis

wcf

I have a WCF service that contains some C# code, which references a C++/CLI dll, which references some native DLLs. I include all of the necessary DLLs in the bin folder for my IIS application, but when IIS loads the managed DLLs, it seems to be copying them to a deep directory like:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\testwcf\73473be6\e625098c\assembly\dl3\aada7c33\85a7332b_2f9acc01

It copies each managed DLL to its own directory and loads it. When it gets to my C++/CLI DLL, it copies it to a directory like above, and then it is unable to load the dependencies. If I manually copy all of the native DLLs into this folder, it will run, but that's not a great solution.

My web.config is the stock one created by VS, with an endpoint defined based on an MSDN article.

<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>

How can I get these DLLs to be picked up automatically?

like image 679
Chris Marasti-Georg Avatar asked Nov 03 '11 14:11

Chris Marasti-Georg


1 Answers

From this post, it seems that the native DLLs need to be available in certain directories or on the path:

The core cause to this problem is in the way the operating system loads native DLL's at runtime. Native DLL's are loaded using the following logic which does not include the Temporary ASP.net Files nor the applications /bin folder. This problem will also occur in any .Net application if the Native DLL is not included in the /bin folder with the .EXE file or if the DLL is not in the Path Environment Variable.

  1. The directory from which the application loaded. In the case of ASP.Net, this will resolve to %windir%\Microsoft.Net\Framework\v###\ or %windir%\system32\inetsrv for IIS 6.
  2. The current directory. In the case of ASP.Net, this will resolve to %windir%\System32\inetsrv for IIS 6. If using the built-in web server, this resolves to a path under C:\Program Files\Microsoft Visual Studio 8.
  3. The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
  4. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  5. The directories that are listed in the PATH environment variable.

The solutions offered are as follows:

  1. Use DLLImport to load the dll using a relative or absolute path at runtime.
  2. Set the PATH Environment Variable so the ASP.Net process can locate the C++ DLL. You can set this property at runtime so that it only affects the process running your code. You can also set this globally in the System Properties (Environment Variables | PATH property). Setting this programmatically does not require a reboot and you can point the PATH to the /bin folder of the web app if you want to be able to do XCopy deployments of your ASP.Net application. Here are the steps to set the Path programmatically from ASP.Net.

There are also some more complex solutions related to #2 which involve programmatically updating the PATH.

like image 157
Chris Marasti-Georg Avatar answered Sep 30 '22 13:09

Chris Marasti-Georg