title: Why SAP Hana DB ADO.NET DLL loading may fail?
body: <p>For a .Net C# app that uses <code>SAP.DATA.HANA.v4.5</code> v2.3.119 and is installed on the runtime machine with the <code>libadonetHDB.dll</code> v2.3.119 with the environment variable <code>HDBADONET</code> pointing to the app folder where <code>libadonetHDB.dll</code> exists. The application works as expected so far on several installations, however one new installation I am seeing it fail producing the <strong><em>The specified module could not be found error</em></strong> exception from HanaConnection below:</p>
  
  <pre><code>The type initializer for 'Sap.Data.Hana.HanaConnection' threw an exception.
  System.Exception: The specified module could not be found
     at Sap.Data.Hana.HanaUnmanagedDll.LoadDll(String dllPath)
     at Sap.Data.Hana.HanaUnmanagedDll..ctor()
     at Sap.Data.Hana.HanaUnmanagedDll.get_Instance()
     at Sap.Data.Hana.HanaConnection..cctor()
  </code></pre>
  
  <p>Also tried just moving the dll to the same folder where the application is installed and the same results are produced.</p>
  
  <p>According to the <a href="https://help.sap.com/viewer/1efad1691c1f496b8b580064a6536c2d/Cloud/en-US/469de1336d6110148c9feec83dbeb4f0.html" rel="nofollow noreferrer">documentation</a>, the dll being in the same folder as the application or via the <code>HDBADONET</code> environment variable path location should work (and have experienced it working on several other installations). This is part of the general workflow for developing and using the ADO.NET library for non-native .NET apps <a href="https://help.sap.com/viewer/52715f71adba4aaeb480d946c742d1f6/2.0.04/en-US/69aae7028abb4740a8f0f36495b477de.html" rel="nofollow noreferrer">documented here</a></p>
  
  <p>I've been trying this as the "Administrator" user and this is a brand new Virtual Machine created (tried both new Windows10 x64 VM and new Windows Server 2016 x64 VM). Also confirmed .NET v4.5+ was installed.</p>
  
  <p>Is it possible that a machine can have a permissions or other policy that affects loading of dlls?</p>
  
  <p>Any clue as to why the SAP Hana ADO.NET DB Connection DLL loading will fail but not in all cases?</p>
  
  <p>Is the <code>libadonetHDB.dll</code> still trying to find and load <code>libSQLDBCHDB.dll</code> or another dll on the machine for some reason? It has been my understanding that using the ADO.NET DLL allowed the machine to not need the other client installation and dlls installed.</p>
  
  <p>Which <code>module</code> is it that can't be found specifically? Is there a way to get the Hana Connection DLL loading to generate more verbose output when it fails?</p>
  
  <p><strong>Update</strong></p>
  
  <p>To confirm that the <code>libadonetHDB.dll</code> is actually found using the <code>HDBADONET</code> environment variable definition, I removed the file and retested and I get a different message:</p>
  
  <pre><code>The type initializer for 'Sap.Data.Hana.HanaConnection' threw an exception.
  System.IO.FileNotFoundException: Cannot find a matching libadonetHDB.dll 
  with version 2.3.119 - check the location in the HDBADONET or PATH 
  environment variables
     at Sap.Data.Hana.HanaUnmanagedDll.SearchNativeDlls()
     at Sap.Data.Hana.HanaUnmanagedDll..ctor()
     at Sap.Data.Hana.HanaUnmanagedDll.get_Instance()
     at Sap.Data.Hana.HanaConnection..cctor()
  </code></pre>
  
  <p>So, the message posted in the original post is coming after <code>libadonetHDB.dll</code> has been found successfully. So it seems like the complaint in the exception message about unable to find or load a module is referring to some other resource or dll it is looking for, but the message is not verbose enough to know what that is. Any ideas?</p>
  
  <p><strong>Update (the solution)</strong></p>
  
  <p>The short answer: </p>
  
  <p>Inspecting <code>libadonetHDB.dll</code> with <a href="https://github.com/lucasg/Dependencies" rel="nofollow noreferrer">Dependencies</a> reveals that <code>msvcr100.dll</code> and <code>msvcp100.dll</code> were both missing on the runtime machine for some reason. Adding those missing DLLs to the app's installation package resolved the issue.</p>
  
  <p>The longer answer:</p>
  
  <p>Thanks to <a href="https://stackoverflow.com/users/2565958/donjuedo">donjuedo</a> for suggesting to interrogate the DLL to see its dependencies. The tool I used on the machine where it was failing is <a href="https://github.com/lucasg/Dependencies" rel="nofollow noreferrer">Dependencies</a> (which requires installation of vc++ redistributable x64 as noted in the readme for it to work) revealed that <code>msvcr100.dll</code> and <code>msvcp100.dll</code> were both missing as dependencies when inspecting <code>libadonetHDB.dll</code>. Note that they were only found to be missing on this particular machine which was a freshly created virtual machine so the inspection and test case had to happen on that machine. </p>
  
  <p>The solution for including the missing DLLs at installation time can be to add <code>msvcr100.dll</code> and <code>msvcp100.dll</code> to either of the following locations:</p>
  
  <ul>
  <li><code>C:\Windows\System32</code> (probably not a preferred solution if you want your app to avoid installing things into the main system folder)</li>
  <li>the folder where the app's exe also exists</li>
  <li>an app's lib subfolder so long as you add the path to that subfolder to the <code>PATH</code> environment variable definition (i.e. <code>set PATH=%PATH%;fullpath\to\app\lib</code>)</li>
  </ul>
  
  <p>These two dlls were already on our development machine and are likely already part of many runtime/client machines that have been around a while and have had other software that needed them. If you don't have these around even in development then download them from Microsoft's official packages as <a href="https://superuser.com/a/1281328">noted here</a> (avoid getting them from 3rd party dll websites if you want be sure they aren't malware hiding in a dll). Ideally the documentation for the SAP HanaDB ADO.NET library should mention the requirements of the runtime machine or that the .NET developer needs to provide these dependent DLLs.</p>