Reference C++ Runtime dll from .net dll - c++

I have a .net dll that requires msvcp110.dll to run. When I use my .net dll in another app the app gives dependency errors. However, when I set the output path of my app to the same folder that contains msvcp110.dll it runs.
Is there some way I can reference msvcp110.dll in my .net dll such that consumers of my dll only have to add a reference to it for their app to run?
Thanks!

For the sake of completeness this seems to be the answer:
Visual C++ 2010: Changes to MSVC runtime deployment (no more SxS with manifest)
I tried installing my dll to the GAC but to no avail - my app still complained about missing dependencies such as msvcr100.dll
o_O

Related

Dependency Walker: Unable to resolve the side by side configuration information contains error

An old MFC application now rebuilt in Visual Studio 2015 Community which uses an old DLL, I'm trying (and tearing my hair) to determine exactly what runtime DLLs are required to properly run the application on machines which doesn't have VS installed.
Target OS is Windows 7. It's a 32 bit application.
The application uses a DLL MAuEASE_s.dll, which uses mfc80.dll and msvcr80.dll DLLs. I don't have the source code of MAuEASE_s.dll so I cannot rebuild/replace it.
On my development machine, the application runs fine with the following set of files put into the same folder:
main executable
MAuEASE_s.dll
mfc80.dll
msvcr80.dll
an ini file required to run the software
To test how it will behave in client machine, I'm using the same set of files on a fresh copy of Windows 7 on a virtual machine. The problem only appears to be specific to mfc/msvcr dependency of MAuEASE_s.dll.
On my machine, even though I've put the DLLs in executable's directory, they are picked from the following folder (found from Dependency Walker):
c:\windows\winsxs\x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_cbf5e994470a1a8f\MFC80.DLL
c:\windows\winsxs\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.6229_none_d089f796442de10e\MSVCR80.DLL
I've copied exactly these two DLLs in executable's directory, then copied the directory into virtual machine running Windows 7. There, Dependency Walker shows error for MAuEASE_s.dll:
The side-by-side configuration information for MAuEASE_s.dll contains error.
Screenshot:
Interestingly, from the manifest of MAuEASE_s.dll I found that it needs 8.0.50727.4053 version of both of the DLLs. But the DLLs found in development machine's c:\windows\winsxs have versions 8.0.50727.6195 and 8.0.50727.6229 but these DLLs still work on development machine.
I've searched the Windows directory for version 8.0.50727.4053 of the DLLs and found them and replaced them in the application's executable directory. The application still works on the development machine.
None of these versions work in the virtual machine.
What's going on and how can I find the exact DLLs to run the application in a PC where Visual Studio is not installed?
My answer doesn't target the problem how to fix the WinSxS error. It just shows how you can force the system to load the application local MFC DLLs.
The MFC80. DLL belongs to VS-2005. They introduced loading DLLs for the MFC side by side. So the Manifest inside the DLL tells the loader to find a public version in the WinSxS directories.
Even if you don't have the source of the MAuEASE_s.dll you can change the behaviour just in changing the embedded manifest. It is just a XML block.
You can just open the DLL in VS and you can modify the resource there. (Export/Import it). Or use another tool to modify the resources of an executable (Resource Hacker etc.)
Long time ago I wrote an article to use the MFC DLL as a private assemblies in your application directory. You just need to remove one token from the manifest. See here.
Alternativly you can create a new manifest as described in the article and replace the existing one with mt.exe.
Binaries built with Visual Studio prior to Visual Studio 2010 referenced dependent DLLs through a manifest (embedded or external). Dependencies referenced through a manifest are searched for in the native side-by-side assembly cache (WinSxS folder) only. The application's directory is not searched. To verify, whether a binary contains an embedded manifest you can use the manifest tool Mt.exe:
mt.exe -inputresource:<filename of binary> -out:manifest.txt
To deploy an application that references DLLs through a manifest, or references DLLs that do, you should deploy those binaries using the respective vcredist_<architecture>.exe download.
If you would rather not have to install files into the native side-by-side assembly cache (because your installer should not need admin rights, for example), you would need to modify the binary (MAuEASE_s.dll in your case). To do so you can retrieve the original manifest first (see above), update the manifest by removing the respective assembly references, and replacing the original RT_MANIFEST resource (using a resource editor like Visual Studio, or Mt.exe):
mt.exe -manifest manifest_new.txt -outputresource:<filename of binary>
Once that's done, you can deploy the DLLs alongside the binary that references them. Note, that this no longer allows you to link against a specific version of a DLL.
As xMRi and IInspectable suggested, I was able to modify the manifest inside the DLL to force load the particular DLL I put in the executable's directory. But it didn't solve the problem. Whenever I was launching the application on the fresh PC, I got the following error:
The application was unable to start correctly (0xc0150002).
In my development machine, I had tons of Visual C++ redistributable versions installed and I found several versions of mfc80.dll and msvcr80.dll in Windows directory. I copied all possible combinations of these two files of different version one by one and tried to launch the application. But it didn't work.
What did work is (what I wanted to avoid) - I opened the uninstall program window from control panel. There I found 3 different versions of Visual C++ 2005 redistributables are installed:
8.0.61001
8.0.50727.42 (this is x64 version)
8.0.56336
I started looking online for these installers. On the fresh PC I started installing the redistributables one by one and trying to launch the application. Finally I found that after installing version 8.0.61001, which is Visual C++ 2005 redistributable SP1 with MFC security update, the application successfully launched.
Now I'm going to pack the installer of this redistributable in my application's installer.

how to add statically link run-time assemblies?

i am trying to run an exe file on another computer that doesn't have visual studios installed.
When i try run the file i get the error : This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
I tried searching for the answer and i lot of websites mention static link run-time assemblies
but i have no idea how to add them into my project.
(Program is in visual studios 2008 in c++ console)
It is hard to tell exactly what libraries are missing. Here are some ideas.
You are deploying a debug version. As non-development computers typically don't have debug libraries deployed (mfc*xxxd.dll & co.) your app cannot start. You should deploy the release version.
You app is built with newer version of C runtime or MFC which is not available on target machine. You should install Visual C++ redistributable package for your version of VS / development tools.
If you can't install this, you should statically link runtime/MFC libraries to your app. Depending on your version of VS, you need to go to project settings and check correct version of runtime libs (static vs dynamic)
If still there are issues, you should check exactly which dlls are missing by using a tool like Dependency Walker on the target machine (actually this should always be the first thing you should do instead of guessing). It will show you which dlls are missing. If everything seems OK, then you are missing some delay-loaded or COM dll - this are not loaded on startup but on demand. You can use DependencyWalker to profile the startup of the app to see exactly what's missing.

Problems with running EXE file built with Visual Studio on another computer

I created a client server application in C++ using Visual Studio.
Now I want to run the client EXE file on another computer (which doesn't have Visual Studio installed),
but when I try run the EXE file, it gives the following error message:
This application has failed to start because the application
configuration is incorrect. Reinstalling the application may fix this
problem.
How can I run the EXE file without installing anything on the computer?
Applications built with Visual Studio depend on Visual C++ Redistibutable (VCRedist). When the program is being linked dynamically, then your binaries will need
MSVCR**.dll (Microsoft C Runtime Library).
On MSDN, there is a nice article called Redistributing Visual C++ Files (for Visual Studio 2008), that states that there are Potential run-time errors in case that required Visual C++ library is not installed:
you may get one of the following error messages depending on the version of Windows on which you try to run your application:
The application failed to initialize properly (0xc0000135).
This application has failed to start because the application configuration is incorrect. Reinstalling application may fix this problem.
The system cannot execute the specified program.
Basically you have two options:
The simplest possible solution is to change the dynamic linking of runtime libraries to static linking. Go to project properties and under C/C++ → Code Generation you will find Runtime Library option. You need to change it from Multi-threaded DLL (/MD) to Multi-threaded (/MT).
Another possible solution is to make sure that the right version of Microsoft VC++ Redistributable Package is installed on the target machine.
But your application might depend on other DLL files as well. In case you want to find out what are the dependencies of your program, there is a great utility called Dependency Walker that will help you in this and many other situations :)
Background:
C++ applications need run-time assemblies (DLL files) to run in any Windows computer.
Normally these run-time assemblies are located at C:\Windows\Winsxs directory.
All the Windows operating systems by default comes with several run time assemblies.
But if your application is developed in a newer version of the run-time assembly environment, the target computer also needs the same version of the run time to exist there.
When you're installing Visual Studio, most newer versions of the run-time assemblies comes to your computer.
Solution:
Finally by anyway the target computer should have the exact run time assemblies. There are a few ways to do this (for more details search each in Google).
Statically link run-time assemblies with your application (troublesome for large application).
Install the C++ redistribution environment on the target computer (the easiest way).
Creating a setup project to deploy the run-time on the target computer when installing the application (not bad).
For deploying run-time assemblies as private assemblies (professional), see here for more details
Conditions:
You must not use .NET framework in your application.
You must not use the common language run-time support for your application
I deployed my program in release instead of debug, and the EXE file now works on the other computer.
I haven't seen that specific error before. Usually it's an error around a missing DLL (Windows redistributable). Assuming there isn't actually a problem with the configuration, you have two choices:
Change the compile mode from Multithreaded DLL to Multithreaded. This can be done from the C++ section of project properties under code generation. In multithreaded mode your binary will be statically linked against the Windows redistributable. This is probably what you want.
Install the Windows redistributable on the target machine. This probably isn't OK, because you state that you don't want to install anything on the target machine.
A warning about option 1: Different versions of Windows have different versions of the redistributable. It's possible to encounter a highly specialized environment in which a statically linked program will not behave as expected.
It look like you're missing some DLL files. Be sure to copy appropriate DLL files along with EXE file.
I am running Visual Studio 2019 and I found a very helpful configuration property to address the problem of moving a simple application to another computer without an installation package.
Open the project Property Pages.
Choose which configurations this change should apply to, I used “All Configurations”.
In the left-hand window click to expand the top node called “Configuration Properties”.
Click on "Advanced". In the right-hand window look for the property called “Copy C++ Runtime to OutDir” and set that to “yes”.
Click OK to close the Properties window.
Rebuild your project. All the necessary dlls will be copied to the project’s output directory. Copy your exe and all dlls to another computer. The exe should find everything it needs to run.

WinSxS fails to load VC++ DLLs

I've got a problem with several VC++ DLLs, which I should include into my .NET/C# project. One VC++ DLL is a C++/CLI DLL, which I use as public interface from my .NET project. The other DLLs are written in native C++. I have no access to the source of the VC++ DLLs, I just have to use them.
I've made a .NET test project and referenced the C++/CLI DLL. No problem, compiler is lucky, great. There's just one problem: when I start the EXE of the .NET program, I get errors about the C++ DLLs because of missing VC++ core DLLs.
sxstrace shows the following (shortened):
INFO: Reference: Microsoft.VC80.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.6195"
INFO: Reference: Microsoft.VC80.OpenMP,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.6195"
INFO: Resolving reference Microsoft.VC80.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.6195"
...
ERROR: Cannot resolve reference Microsoft.VC80.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="8.0.50727.6195".
Now I'm no fool and tried several things. I've read much about WinSxS to get a deeper understanding about what's going on.
Now I'm at the point, where it's getting weired for me. The system where I want to execute the program has the VC++ Redistributable package in the current version 8.0.50727.762 (SP1) installed. I know that there's a policy file for Microsoft.VC80.CRT in winsxs that redirects all versions of this assembly to the current version 8.0.50727.762 (that's the solution for the problem at http://blogs.msdn.com/b/nikolad/archive/2007/03/29/a-solution-to-two-references-to-different-versions-of-crt-mfc-atl-in-one-application-manifest-file.aspx).
But as the error above says, this policy file doesn't seem to work or isn't taken into account. The system just wants to find the 8.0.50727.6195 version of the assembly.
Now that's the first question: what's the problem here? After I got this figured out, I could solve the initial problem...
Ok, now it works - thanks for your help.
I figured out two problems that had to be solved:
1) I had to install the "Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package MFC Security Update", which deploys version 8.0.50727.6195 of the VC++ assemblies. This update was hard to find at the Microsoft servers, so here's the link: http://www.microsoft.com/download/en/details.aspx?id=26347
Normally you only find the 8.0.50727.762 version ("Visual C++ 2005 Service Pack 1 Redistributable Package), which is outdated. Since the C++ DLLs were compiled against 6195, installing the update solved the first problem.
2) While the C++/CLI DLL was compiled in Release mode, the native C++ DLLs below had been delivered in Debug mode. Now the Microsoft license agreement prohibits deploying the VC++ Debug DLLs and the VC++ Redist Packages don't include the VC++ Debug DLLs.
http://msdn.microsoft.com/en-us/library/aa985618.aspx says:
Debug versions of an application are not redistributable and none of the debug versions of the various Visual C++ dynamic-link libraries (DLLs) are redistributable.
Solution: the developers of the native C++ DLLs gave me a release version and everything works fine...

DLLNotFoundException

I am using a DLL that is a plugin for a game engine called Unity3d. I created the DLL in Visual C++ Express 2010 on windows 7 64 bit Ultimate Edition. The DLL functions properly on the machine that it was originally created on.
The problem is that the DLL is not functioning in the Unity3d Editor on another machine and giving an error that basically states that the DLL is missing some of its dependencies. The target machine is running Windows 7 Home 64 bit (if this is relevant)
Results from the error log of Dependency Walker:
Error: The Side-by-Side configuration information for
"c:\users\dewayne\desktop\shared\vrpnplugin\unityplugin\build\release\OPTITRACKPLUGIN.DLL"
contains errors. The application has failed to start because its
side-by-side configuration is incorrect. Please see the application
event log or use the command-line sxstrace.exe tool for more detail
(14001).
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
Error: Modules with different CPU types were found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
The Visual C++ Express 2010 project and solution file can be found here. The zip is 79MB and also contains its dependencies.
The DLL in question is OptiTrackPlugin.dll
Check dependencies in your dll. I use depends.exe dependency walker, it used to be bundled with Visual C++, but MS no longer provides it. You can download it separately: http://www.dependencywalker.com/
Probably you missed the MS C++ Runtime on the client that's using your DLL.
If you've builded it in visual studio, you need the CRT and C++ RT installed on your clients. Dependency Walker surely will detect it.
Cheers.