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 { /// <summary> /// The main entry point for the application. /// </summary> [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