I have an application that directly references a dll file: POSLink.dll
.
In order to get this to run on my local machine, I have to manually copy the following dlls to the output directory: libea32.dll
and ssleay32.dll
.
When I run the application on my local machine, it succeeds.
When I run the application on the target machine, I get the following error:
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'POSLink.dll' or one of its dependencies. The specified module could not be found.
at FileNotFoundExceptionExample.Program.Main(String[] args)
This is my SSCCE
using POSLink;
using System;
namespace FileNotFoundExceptionExample
{
class Program
{
static void Main(string[] args)
{
// this is stuff found in the POSLink namespace
var commSetting = new CommSetting();
commSetting.saveFile();
Console.WriteLine("Success");
}
}
}
I tried using Dependency Walker on POSLink.dll, but that wasn't very useful to me because there are 381 errors that show up, and they show up when I run it on the successful machine too.
How do I even begin troubleshooting this error?
When I run the Fuision log viewer and then run the application on the target machine, I get the following log:
* Assembly Binder Log Entry (7/19/2016 @ 2:18:48 PM) *
The operation was successful. Bind result: hr = 0x0. The operation
completed successfully.Assembly manager loaded from:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll Running under
executable
C:\Users\Omitted\Desktop\notfoundexceptionexample\debug \FileNotFoundExceptionExample.exe
--- A detailed error log follows.=== Pre-bind state information === LOG: DisplayName = POSLink, Version=1.0.5773.36725, Culture=neutral,
PublicKeyToken=f3876d2e4b7eb819 (Fully-specified) LOG: Appbase =
file:///C:/Users/Omitted/Desktop/notfoundexceptionexample/debug/ LOG:
Initial PrivatePath = NULL LOG: Dynamic Base = NULL LOG: Cache Base =
NULL LOG: AppName = FileNotFoundExceptionExample.exe Calling assembly
: FileNotFoundExceptionExample, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null.
=== LOG: This bind starts in default load context. LOG: Using application configuration file:
C:\Users\Omitted\Desktop\notfoundexceptionexample\debug\FileNotFoundExceptionExample.exe.Config
LOG: Using host configuration file: LOG: Using machine configuration
file from
C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: POSLink, Version=1.0.5773.36725,
Culture=neutral, PublicKeyToken=f3876d2e4b7eb819 LOG: GAC Lookup was
unsuccessful. LOG: Attempting download of new URL
file:///C:/Users/Omitted/Desktop/notfoundexceptionexample/debug/POSLink.DLL.
LOG: Assembly download was successful. Attempting setup of file:
C:\Users\Omitted\Desktop\notfoundexceptionexample\debug\POSLink.dll
LOG: Entering run-from-source setup phase. LOG: Assembly Name is:
POSLink, Version=1.0.5773.36725, Culture=neutral,
PublicKeyToken=f3876d2e4b7eb819 LOG: Binding succeeds. Returns
assembly from
C:\Users\Omitted\Desktop\notfoundexceptionexample\debug\POSLink.dll.
LOG: Assembly is loaded in default load context.
So, as it turns out, there is a way to filter through all the unimportant errors that dependency walker tells you about.
Frankly I'm embarrassed that I didn't try this before. I had only assumed that the number of errors was the same based on how I assumed the log was laid out.
The log is the middle window that's selected in this screenshot.
As it turns out msvcr120.dll was indeed what was missing, and finding a suitable one, and dropping it into my output directory fixed the problem.
NOTE: msvcr120.dll is the Visual C++ 2013 Runtime. Instead of manually copying dlls around, the proper solution is installing the Visual C++ Redistributable Packages for Visual Studio 2013