MSVCRT backwards compatible? - visual-c++

let's say that DLL A as the CRT 8.0.50727.762 as dependency. This DLL is used in a exe project that is linked dynamically (/MD) with "Use Of MFC" = "Use Standard Windows Libraries".
Both the DLL and the project using the DLL are using VS 2005, yet the project building machine has a newer CRT. So the exe itself has a dependency to 8.0.50727.6195 in its manifest.
Now I have two question:
Is my understanding correct that the CRT versions are backwards compatible?
So when I deploy the project and add the CRT assemblies version 8.0.50727.6195 to the exe's working directory it should work on any client no matter what is in his WinSXS cache right?

No. CRT or MFC is not backward compatible. You must install appropriate Visual C++ Runtime on client's machine, ensuring that:
The version should match (VC7, VC8,.. VC14 etc.)
The bit-ness should match. If your application is 32-bit, you need 32-bit redistributable, and same for x64.
The service pack version must also match!
It should be noted that all of them can co-exist! VC10 RTM, VC10 SP2, VC10 x64 RTM.. all can co-exist.

Related

Cannot register COM DLL built with VS2012/VC++ on 32-bit machine

I built a C++ based COM object using Visual Studio 2012. It registers and works fine on 64-bit machines (called by 32-bit code and calling a 32-bit out-of-process COM server) but does not register on 32-bit machines (neither XP nor Win7 32-bit). The message from regsvr32 is
LoadLibrary("comobj.dll") failed - The specified procedure could not be found.
The project was originally built with Visual Studio 6 (7 years ago). It uses ATL macros such as BEGIN_COM_MAP and BEGIN_SINK_MAP to declare its implementation of various interfaces. It had to be re-compiled because the COM server it was invoking changed (new ProgID, new GUID, new type library, etc). Other than making those adjustments, and using current VS, there were no (intentional) changes -- there certainly was nothing in the old equivalent of the project file that would have pointed to 64-bitness.
Examining the DLL with the 64-bit version of DEPENDS.EXE shows "64" icons next to the standard referenced DLLs like KERNEL32 and USER32. Other than having built the DLL on a 64-bit machine, there is nothing "64-bit" about the DLL that I can find. The target is explicitly Win32 (not X64).
Examining the DLL with the 32-bit version of DEPENDS.EXE (on Windows XP running under Virtual PC) shows KERNEL32.DLL with a red icon, apparently because there are references to FlsAlloc FlsFree FlsGetValue FlsSetValue that do not exist in the 32-bit KERNEL32.DLL. (I have no idea what those are and don't know where those references come from -- perhaps from the copy of MFC on the 64-bit machine where the compile was done?)
Could it be that I have to install VS2012 on XP and re-compile there? How could that really be what needs to be done to build a Win32 COM object in C++ using current Visual Studio?
Does anyone know where I might look? I've checked all the project and solution options and nothing seems set to 64-bit. The option under "Use of MFC" is set to "Use Standard Windows Libraries" -- that's probably the answer but if that's not portable to 32-bit Windows it's hardly using only "standard libraries". (I will be trying changes to that after sending this.)
Thanks in advance for any advice.
Default toolset coming with Visual Studio 2012 produces output incompatible with Windows XP, through using certain APIs introduced only later with Vista.
In order to both utilize the power and feature richness of the latest Microsoft C++ compiler, and be still compatible with Windows XP, you need to use an alternate toolset codename "v110_xp" introduced with Visual Studio 2012 Update 1. At the moment the latest update available is Visual Studio Update 3, and you might want to simply install latest available updates for Visual Studio.
You have the setting available under Project Settings:
See more here: Configuring C++ 11 Programs for Windows XP.

Which Windows Libraries are missing from the Visual C++ Redistributable Package?

I am using JNI to interface to a CAN driver I wrote using MSVC++ 2012. Everything compiles and runs fine - but only on my computer. Whenever I try to run on any other computer, I get the JNI "UnsatisfiedLinkError" - can't find dependent libraries. I've implemented JNI before, and typically this issue is resolved by simply installing the Microsoft Visual C++ Redistributable Package before running my program. The Redistributable does not solve my issue, however, installing the entire MSVC++ Express 2012 IDE on the computer in question seems to make everything work just fine. Thus, I assume this means that there is some dependency that gets installed and added to PATH when the IDE is installed but not when the Redistributable is installed. Just for verification, I uninstalled the IDE and my JNI driver failed to load once again. The primary difference between this and my other implementations of JNI is that I use Windows.h since it is required for the CAN API I use in my driver. Any ideas on any libraries installed with the IDE but not the Redistributable and whose prototypes are included with Windows.h? (Note: I am aware that Windows.h includes a number of headers itself but I imagine the other criteria make the issue a bit more specific.)
First guess: You are installing a debug build intead of a release build. Debug builds depend on debug versions of the CRT, which cannnot be redistributed.
Check that you are using the right "Microsoft Visual C++ Redistributable Package". There are 2012, 2012 Update 1 and 2012 Update 2 (as well as many for 2010, 2008, ...).
Assuming your dependencies are load-time DLLs, you can use Depends to find out what's missing. (Note: you'll typically see some delay-load DLLs that are "missing". Ignore thoses; See the FAQ.)
Of course, once you find out the name and path of the missing DLL, you'll have to find out what redist package installs it.

wix custom action missing dll MSVCR100D.dll

I am writing an installer using wix. I have also written custom actions. But while installing the MSI the installation fails because the target system does not have MSVCR100D.dll
I am linking using /MTd option which is what the docs I read suggested for static linking.
Can anyone please let me know how to link msvcr100d.dll statically so that even if msvcr100d.dll is not present on the target system, my MSI installation succeeds?
The "D" in MSVCR100D.dll indicates that your native custom action DLL is a debug DLL. The "D" dependency won't be on the target machine unless they have various SDKs installed. Rebuild your DLL in release and the dependency will change to MSVCR100.dll
Also, since you are using WiX / Votive, there is a Visual Studio WiX C++ CA project type that creates the project for you. My experience has been that all of the default compiler and linker settings are good to go out of the box when you use that project type.
I have noticed the same problem. In my case, I am trying to debug my custom actions running in the context of the installer, so I do want to install debug versions.
The Visual Studio debug CRT DLL's are not redistributable, by Microsoft policy. Apparently, it seems furthermore that a 64-bit DLL compiled with Visual Studio 2010 using /MTd (static linking, debug configuration) produces output with a dependency on MSVCR100D.dll. In the 64-bit release configuration, as expected, compiling with /MT results in no dependency on MSVCR100.dll.
One solution is to install Visual Studio on the target test machine. Microsoft offers further suggestions here.

Are D3D9 apps tied to exact D3DX DLL version?

If I built my app against D3DX June2007_d3dx9_34 and the target system has a newer version Nov2007_d3dx9_36 should that be a problem?
I distribute D3DX DLLs using MS' redist-installer tool but I noticed one one 'clean' PC (no D3DX previously installed) I got an error about missing D3DX DLL. Before trying to figure out if the installer itself is not working, I wondered if maybe supplying a too-new version of the DLL is the problem - will the app be looking for a DLL with the exact name?
D3DX libraries are not backwards-compatible, and the API may change between versions. So the target system must have the same version of D3DX that you build your application with - a newer version won't work.
If you use Dependency Walker on your application, it should show you that there's a dependency on a DLL with the exact version number.
The redistributable in the DirectX SDK includes the whole history of the D3DX dlls. Installing the latest version of the DirectX redistributable should have your system end up with every version of these dlls. It is possible and allowed for applications to only install the files they need by deleting cab files out of the redistributable's directory structure, in order to reduce the size of the redistributable components, and this is how you can end up with having 43 of the dll but not 37 for instance.
If you remove the dependency of D3DX and D3DCOMPILER dll's from your application you can ensure the application will work as the d3d9 d3d10 and d3d11 core dlls are version-agnostic and are also tied to the windows service pack releases (i.e. D3D11 for Vista comes from Vista SP2 or Win7 stock installs for example).
Another possible way to remove the dependency and let the app startup is to make the dll a delay load module, so it is only loaded when needed (such as compiling shaders on a development environment). As long as you are sure the shaders exist on end-user machines properly it won't need to compile shaders and won't crash. Calling LoadLibrary and invoking the functions manually would be a safer choice with a way better error message of your choosing, but is a lot more work.

After building exe using VS 2010 C++ missing MSVCP100.dll

I have designed an application that requires no install and can be used by non-administrators. I would rather not lose this functionality but when I use the .exe on other computers than the one I programmed it on I get an error that a missing MSVCP100.dll is preventing the file from executing.
What am I doing wrong here? How do I include the file in my release build?
Thanks!
Configure your project to statically link to the C/C++ runtime instead of linking to the runtime DLL:
Configuration Properties | C/C++ | Code Generation | Runtime Library
Select Multi-threaded (/MT) (or Multi-threaded Debug (/MTd) for your debug build).
As an alternative, you should be able to get xcopy deployment of the C/C++ runtime DLL using the technique documented on http://msdn.microsoft.com/en-us/library/ms235291.aspx under the heading "Deploying Visual C++ library DLLs as private assemblies". I haven't tried that technique, as it's generally simpler to just statically link if you need xcopy installation of a native C++ program.
http://msdn.microsoft.com/en-us/library/ms235299.aspx
Distributing apps that have been compiled with Visual C++ requires distributing the C++ runtime .dlls that your app uses. In your case, I assume you want to just distribute a folder, so follow the directions (appropriately modified for your app) here:
http://msdn.microsoft.com/en-us/library/dd293565.aspx
Or just copy msvcp100.dll into your application's directory alongside the .exe and you'll be good to go.
32-bit msvcp100.dll is in C:\Windows\SysWOW64\
64-bit msvcp100.dll is in C:\Windows\System32\
What am I doing wrong here
What you had was dll hell. You had unintentionally used a dynamic linkage with the previous compiler where it just happened on most target systems there was an appropriate C runtime. Windows often included VC 6 CRT, and with more recent SP even VC7 & 8 CRT.
When you changed to the latest VC compiler most systems will not have the new VC runtime pre installed for you.
As Michael Burr says, you can have your 'no install' back if you link statically.
Or you could include the CRT and manifest in the same folder, still doesn't require install.
Or include the vcredist.exe from VS2010 and have a 1 off install
You need to install Microsoft Visual C++ 2010 Redistributable Package.

Resources