Chilkat .NET Assemblies – Matching Visual Studio versions to .NET Framework Versions to VC++ Runtime Versions.


The .NET Framework version that corresponds to each Visual Studio release is as follows:

VS2015 — .NET 4.6
VS2013 — .NET 4.5 (actually 4.5.1, but we only care about major/minor numbers)
VS2012 — .NET 4.5
VS2010 — .NET 4.0
VS2008 — .NET 3.5
VS2005 — .NET 2.0

When using Chilkat .NET for a particular .NET Framework version, the corresponding VC++ Runtime redist (from Microsoft) needs to be installed on the system. The VC++ redist that is needed, and the download links, are shown below:

VS2015 .NET 4.6 Chilkat .NET for 4.6 needs VC++ 2015 runtime (also known as VC++ 14)
VS2013 .NET 4.5 Chilkat .NET for 4.5 (built with VS2013) needs VC++ 2013 runtime (also known as VC++ 12)
VS2012 .NET 4.5 Chilkat .NET for 4.5 (built with VS2012) needs VC++ 2012 runtime (also known as VC++ 11)
VS2010 .NET 4.0 Chilkat .NET for 4.0 needs VC++ 2010 runtime (x86)(x64) (also known as VC++ 10)
VS2005/2008 .NET 2.0/3.5 Chilkat .NET for 2.0/3.5 needs VC++ 2005 runtime (x86)(x64) (also known as VC++ 8)

Dynamically Loading a 32-bit or 64-bit .NET Assembly at Runtime

The Chilkat .NET assembly is a mixed-mode assembly, meaning that it exposes a managed API, but the inner core is native. Therefore, as for any DLL, a 32-bit process must load a 32-bit DLL, and a 64-bit process must load a 64-bit DLL.

On a 32-bit system, there is never any choice and therefore this whole subject is moot.

On a 64-bit system, a 100% managed .NET app can run as either a 64-bit process or as a 32-bit process. Visual Studio projects have a setting named “Prefer 32-bit”, which is by-default ON, which means the app will always run as a 32-bit process. In that case, it is the 32-bit DLL that must be loaded (always), and again this subject is moot.

I recommend this: If your app does not use more than 4GB of memory, then simply choose to run 32-bit everywhere. You have better things to do with your time. Performance is usually just as good (if not better) running 32-bit.

I also recommend this: As time goes on, it gets more and more difficult to find yourself actually running on a 32-bit system. I’m sure it’s been many years since it’s been possible to buy a new computer running 32-bit Windows, and Microsoft is ending support for the OS’s what can run 32-bit Windows. So.. if your app will NEVER encounter a 32-bit system, and it needs more than 4GB of memory, then uncheck the “Prefer 32-bit” setting in your Visual Studio app, and ALWAYS run 64-bit. Again, you have better things to do with your time than monkeying around with additional unnecessary complexity.

If you’re in the situation where you desire either 32-bit or 64-bit, then there are two solutions:

  1. Make sure the 32-bit Chilkat DLL is distributed with your app to systems where it will run 32-bit, and the 64-bit Chilkat DLL is distributed with your app to systems where it will run 64-bit. Or…
  2. Dynamically load either the 32-bit or 64-bit DLL at runtime. Here are links to two possible solutions for doing so.

Dynamically Loading .NET Assembly (32-bit or 64-bit)

Found a nice technique for dynamically loading a native .NET assembly and automatically choosing the appropriate one to match the loading process’s address space (32-bit or 64-bit). The source is located here: and reproduced here:

I prefer another solution to this problem. It allows you to have a mix of 32 and 64 bit apps in the same directory.

I install both 32 and 64 bit assemblies into the same directory by renaming them.


In the project references you just refer to the one you want for that particular project.

Then I get them to load using the AssemblyResolve event which fires when a dll can’t be found.

In Program.Main() add this

	AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

Then add this code somewhere

	private const string ChilkatRootFileName = "ChilkatDotNet4";

	static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		if (args.Name.StartsWith(ChilkatRootFileName, StringComparison.InvariantCultureIgnoreCase))
			string path = string.Empty;
			string current_folder = string.Empty;
				current_folder = Path.GetDirectoryName(new Uri(
				path = Path.Combine(current_folder, ChilkatRootFileName + 
					string.Format("-{0}.dll", IntPtr.Size == 4 ? "32" : "64"));
				Assembly assembly = Assembly.LoadFrom(path);
				return assembly;
			catch (Exception ex)
		return null;