C++ / CLI - How To Use Managed C++ DLL when Microsoft Visual C++ Redistributable is not installed?
If your .NET application uses components written in Managed C++, you face the necessity to distribute Microsoft Visual C++ Redistributable with it. If one attempts to launch such application in a system that doesn’t have the corresponding Microsoft Visual C++ Redistributable installed, the user will get a warning “This application has failed to start because the application configuration is incorrect”. Why this happens, and can that be done without installing Microsoft Visual C++ Redistributable?
With the common approach, a DLL written in Managed C++ has a dependency from Microsoft Visual C++ Runtime, DLL files from which cannot be linked statically. The traditional solution is the inclusion of Microsoft Visual C++ Redistributable in the setup file.
With BoxedApp SDK, you can emulate the availability of Microsoft Visual C++ Runtime. Right after the application is launched, before using the components compiled in Managed C++, create the files, from which the Managed C++ DLL depends (how to find paths to dependencies):
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
namespace WindowsApplication1
{
static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();
string PathOfWinSxS =
Directory.GetParent(Environment.SystemDirectory).FullName +
@"\WinSxS";
if (!Directory.Exists(PathOfWinSxS))
// Win2k
PathOfWinSxS = Application.StartupPath;
Stream fromStream =
Assembly.
GetExecutingAssembly().
GetManifestResourceStream("WindowsApplication1.res.msvcm80d.dll");
CreateDLLInMemory(
PathOfWinSxS +
@"\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcm80d.dll",
fromStream);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
BoxedAppSDK.NativeMethods.BoxedAppSDK_Exit();
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
static void CreateDLLInMemory(string strVirtualPath, Stream stream)
{
const int BufferSize = 1024;
byte[] buffer = new byte[BufferSize];
IntPtr hHandle =
BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
strVirtualPath,
BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
BoxedAppSDK.NativeMethods.EFileShare.Read,
IntPtr.Zero,
BoxedAppSDK.NativeMethods.ECreationDisposition.New,
BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
IntPtr.Zero);
CloseHandle(hHandle);
int nReadBytes;
using (FileStream VirtualFileStream = new FileStream(strVirtualPath, FileMode.Open))
{
while ((nReadBytes = stream.Read(buffer, 0, BufferSize)) > 0)
VirtualFileStream.Write(buffer, 0, nReadBytes);
}
}
}
}
To find out, which exact DLL files does your Managed C++ DLL has dependencies from, use the depends.exe application from Visual Studio setup. Open your Managed C++ DLL in depends.exe, and you will easily find, which VC++ Runtime components it depends from:



Write a Comment
You must be logged in to post a comment. Log in