Search code examples
c#visual-c++c++-cli

Cannot use a C++/CLI DLL unless visual studio is installed


Intro

I'm Developing a tool that can interpret and use API Blueprints.

I created a new console app, added SnowCrash.NET nuget package and wrote this code:

    static void Main(string[] args)
    {
        snowcrashCLR.Blueprint blueprint;
        snowcrashCLR.Result result;

        var path = args.Length > 1 ? args[1] : @"c:\";

        snowcrashCLR.SnowCrashCLR.parse(path, out blueprint, out result);
        if (result != null)
        {
            var warnings = result.GetWarningsCs();
            foreach (var warning in warnings)
            {
                Console.WriteLine("{0}: {1}", warning.code, warning.message);
            }
        }
    }

Problem

When I deployed my code (copied the bin folder) to a different computer than my development environment, I get a FileNotFoundException pointing to SnowCrash.dll

here is a snapshop from the error message:

Could not load file or assembly 'snowcrashCLR.DLL' or one of its dependencies. The specified module could not be found.

Details:

[FileNotFoundException: Could not load file or assembly 'snowcrashCLR.DLL' or one of its dependencies. The specified module could not be found.]
   System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
   System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +34
   System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +152
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +77
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +16
   System.Reflection.Assembly.Load(String assemblyString) +28

What I've tried so far

  • I used sysinternal procmon on both machines to compare and it looks like my dev machine (which runs fine) is loading this DLL:

Load Image C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualC.STLCLR\v4.0_2.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualC.STLCLR.dll

  • My computer, which the application works fine on, has these runtimes installed
MS Visual C++ 2005 Redist (x64)
MS Visual C++ 2008 Redist (x64) 9.0.30729.4148
MS Visual C++ 2008 Redist (x64) 9.0.30729.6161
MS Visual C++ 2008 Redist (x86) 9.0.30729.4148
MS Visual C++ 2008 Redist (x86) 9.0.30729.6161
MS Visual C++ 2010 x64 Redist - 10.0.40219
MS Visual C++ 2013 x64 Redist - 12.0.30501
MS Visual C++ 2013 x86 Redist - 12.0.30501
  • On the computer that had the error (did not work), I installed the same identical list of runtimes above, but that did not solve the problem or made it work.

  • I installed visual studio on that computer, that did not work previously, and when I tried my application and it worked

Your help is greatly appreciated if you have better knowledge or battle scars with a similar issue.


Solution

  • By doing lots of digging on the inter-webs I found that there was a missing dependency that the SnowCrash DLL needs in order to run, which was Visual C++ runtime 2012 x86.

    since its a mixed (managed CLR + Native) DLL, it needs the C++ MFC library, that comes with the VC++ runtime. and it must be the right version in order to run properly.

    Installing the runtime from this MSDN URL onto the target computer solved my problem.