1

EDIT: I found a way to get it to work locally, but on Azure I still get System.IO.FileNotFoundException on that assembly. My question might seem like a duplicate to this question here. But it is slightly different, I have already tried that solution and it did not work. Here are the details.

I have an ASP.NET MVC App that has a Reference added to a third party CLR DLL. That third-party DLL requires a native DLL which it invokes. Now if I had control over where the Shadow Copying occurs and what is copied, I would be in paradise. The Shadow Copying misses copying that native DLL despite it's Build Action set as Content and Copy To Output Dir set as Copy Always.

So I searched internet and ran into this discussion on SO, which is same as what was mentioned earlier. I tried adding the code that sets the PATH Environment Variable inside Application_Init and Application_Start of Global.asax, I set the breakpoints in both the methods and to my surprise I get the ASP.NET Error Page before it even hits the breakpoint. This leads me to believe that the referenced assembly at the time of binding hits the native DLL and invokes it. What can I do? Can I delay the reference binding somehow? EDIT: Yes we can, I opened the Referenced DLL's code which was written in Managed C++, I adjusted the linker setting to Delay Load the Native DLL and now my Application_Start executes first. Yayy! but that does not solve the same problem I am having on Azure

Here is the test solution with DLLs

Here is the source code for the Native DLL

Here is the source code for the Referenced Assembly that uses the Native DLL

To download the Native DLL distribution, Go to their distribution page, choose the windows archive with the bitness you desire (I am using 32-bit), and you will find amzi.dll inside APIs/bin directory.

Community
  • 1
  • 1
fahadash
  • 3,133
  • 1
  • 30
  • 59

2 Answers2

1

Actual problem was the wrapper DLL not recognized on Azure server because of lack of support of earlier frameworks and toolsets, as well as Debug CRT.

  1. I used XDT/Application_Start to set the PATH environment variable to include the location of my native DLL

  2. I upgraded my Managed C++ Wrapper DLL to use Toolset 14.0 and .NET 4.6.2

  3. Used Linker Setting of /DELAYLOAD on Managed C++ Wrapper DLL

fahadash
  • 3,133
  • 1
  • 30
  • 59
0

After downloaded the DLLs and source code which you provided, I found that the native DLL depends on x64 platform. Firstly, we need to change the Platform property of our web app to x64 using Azure portal. If the platform button is disabled, you need to scale up your web app plan to Basic level plan or higher level.

enter image description here

In addition, the original path may end with “;”, so we need to check whether it contains “;” and append right content to it. Code below is for your reference.

string path = Environment.GetEnvironmentVariable("PATH");

Trace.TraceError(path);
string binDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Bin");
Trace.TraceError(binDir);
if (path.EndsWith(";"))
{
    Environment.SetEnvironmentVariable("PATH", path + binDir);
}
else
{
    Environment.SetEnvironmentVariable("PATH", path + ";" + binDir);
}

To test whether the path is set successfully, you could add a page to test it.

public ActionResult GetPath()
{
    string path = Environment.GetEnvironmentVariable("PATH");
    return Content(path);
}

After path is set, the native DLL can be load successfully on my side.

On my end I added a throw new ApplicationException("Test") at the beginning of Application_Start and instead of getting my test exception, I was getting the DLL load error.

It means the setting path code will not executed. To fix it, you could remove the native DLL reference from your web application. Now your application could work fine and set the path environment variable. Then you could add the native DLL reference back.

Another way to do it is that we could create a webjobs and set the path environment variable in webjobs and deploy this webjobs before deploying your web application.

I am using 32-bit distributions, my native dlls depends on x86/32-bit.

If you use 32-bit distributions and the platform targets of your CLR DLL and your web application are set to "x86 or Any CPU", you won't need to change platform to x64 in web app. Please change it back to x86.

enter image description here

Amor
  • 8,325
  • 2
  • 19
  • 21
  • I will try that. On my end I added a `throw new ApplicationException("Test")` at the beginning of `Application_Start` and instead of getting my test exception, I was getting the DLL load error. – fahadash Mar 13 '17 at 13:43
  • Also I am working with 32-bit version of native dll that I downloaded from [Their distributions repository page](https://github.com/AmziLS/distribution) Can I not use 32-bit so I could use the `Shared Tier` instead of the expensive `Basic`? – fahadash Mar 13 '17 at 14:19
  • I tried to change my platform to 64-bit and I have the same issue. I am using 32-bit distributions, my native dlls depends on x86/32-bit. – fahadash Mar 14 '17 at 03:32
  • I appreciate the effort. I checked using Dependency Walker to make sure my native DLL was in fact 32-bit, I rebuilt all my binaries in x86, my Azure platform is set to 32-bit, I even adjusted the path environment variable using [XDT File and saw the correct path in KUDU](https://social.msdn.microsoft.com/Forums/en-US/8d5c123b-677d-4dd2-8cb1-30012b2f17f3/how-to-copy-native-dlls-to-system32?forum=windowsazurewebsitespreview) and I continue to see that assembly load exception. – fahadash Mar 14 '17 at 19:25
  • I also put [my application on Github](https://github.com/fahadash/AzureTest) and created a WebHook to automatically rebuild my Azure Web Site when the repo changes. Could you Fork it, make a change you think that is going to work and submit me a pull request? Or give me your user ID I will allow you access to commit. My website can be [browsed here](http://testmvcservice20170312114004.azurewebsites.net/) once a change is Pushed to the repo, the automated deployment will rebuild the website. – fahadash Mar 14 '17 at 19:29