Running C++ binaries without the runtime redistributable (Server2k3, XPSP3) - c++

Having written a CGI application in Visual Studio 2008 and debigged it locally, I uploaded it to a Windows Server 2003 OS where it promptly failed to run.
I am guessing I need to install the wretched Runtime distributable, but after reading this:
http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/
I am wondering if it makes more sense to ignore this side by side stuff and just re-write the app.
I am guessing Windows Server 2003 does not have MSCRVT version I need?
Does Windows Server 2003 have it?
When it comes to deploying thick clients, I would like to distribute the required dlls with my app.
What are they assuming I just INCLUDE iostream, sstream, string?
Does it change significantly if I add windows.h?
Added:
Using the /MT switch recommended below
C / C++ -> Code Generation -> Runtime Library -> Multi-threaded(/MT)
(You will probably need to do a clean:
Build -> Clean
in order to avoid the error message
"Failed to save the updated manifest to the file")
bloated my app from 38k to 573k. Thats what I call Significant (imagine if that were your salary). Since many instances of this app will be loaded and unloaded constantly (requiring precious memory and processor resources) I would like to find a better (smaller) solution.
I understand this is not important for many situations today and not the focus of many developers, hence the trend to .NOT and 60MB runtimes, but this is what I want to do.
Added:
After removing the debugging to get the project to compile:
Project -> Propeties -> c/c++ -> Preprocessor -> Preprocessor Definitions (remove DEBUG;)
the size was reduced to 300k, and it will run.
Added:
As suggested by Chris Becke below, copying:
msvcm90.dll
msvcp90.dll
msvcr90.dll
Microsoft.VC90.CRT.manifest
To the directory of the application will provide all the runtime needed.
Using Visual Studio 6 has been suggested a few times, but it does not support Vista (or Windows 7 we assume) Other solutions that do not require a runtime distributable would probably me MASM or even a flavor of Basic. Unfortunately that defeats the purpose of using a high level OOP language like C++.
So long as I do need to require the C++ redistributable be installed, the trade off is an additional 260k. Thats acceptable

Let me revise my answer:
You have a few options:
1) Install the VC++2008 runtime. You can download and installer for them. Merge modules for them are also available.
2) Link against the runtime statically (/MT or C/C++ -> Code Generation -> Runtime Library: Multi-threaded). This will increase the size of your executable, but it won't depend on any Dlls. If you are worried about size, only use the C standard library or only use the Windows API directly.
3) Use an older version of VC++. 2005 and earlier did not require the runtime to be installed. The Dlls could be placed in the same directory as the executable. If you use VC++6.0 the runtimes will be installed on all versions of windows, otherwise you need to install it yourself.

A fuller list of options:
Rewrite the app so that theres no C/C++ usage at all.
Switch to Visual Studio 6 or a mingw based toolset like Code::Blocks - these use the already distributed msvcrt.dll as their runtime.
Build using the /MT switch. This builds the necessary runtime functions into your exe. Which will bloat it. But that bloat (frankly) is less overhead than loading separate dll's.
Distribute the VS9 runtime as a 'private sxs' install. This entails copying the contents of C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT into the same folder as your application's exe. If you have applied SP1, then this folder will contain the SP1 runtime, but your application will be asking for the RTM runtime (go figure). Add _BIND_TO_CURRENT_CRT_VERSION to your projects defines, rebuild and that should sort itself out.
There is apparently a vc_redist.exe that can be obtained for VS9. Find that or figure out the MSI or installer mojo required to actually install the above assembly (being the contents of Microsoft.VC90.CRT) into the shared sxs store.

Related

Windows 10 app with dynamically linked VC++ does not start even after installation of VC++ 2017 redistributable

We're currently beta testing a Windows application which is built with the latest Visual Studio in C++ and runs on Windows 10. The application dynamically links the VC++ libraries (static linkage is not an option for us).
On 75% of our testers' machines (including all our dev machines), the application works out of the box after installing, but with some others it does not start and fails (presumably) during the process of loading dynamic system libraries (since it does not trigger any kind of exception that would write a minidump as with runtime errors).
Some of these users have had errors about missing runtime dlls which were solved after installing the latest VC++ 2017 redistributable, however the application still would not run.
One user has also checked the library dependencies with the Dependencies tool (https://github.com/lucasg/Dependencies), but his results show nothing strange - there is no obvious difference between the output on a working machine and on his own. There are a few question marks (see screenshot: missing modules as shown in Dependencies) next to some UCRT subdependencies but they are there on working machines as well so I presume they are false positives.
I've also tried to deploy the relevant 40 something UCRT and VC++ dlls as an app local deploy next to the executable but it still wouldn't open on the affected machines (I might have missed some relevant ones, or they were still referenced from the System32 folder)
How would you debug such a problem, providing we cannot reproduce it locally (it works out of the box on two completely new devices with a fresh Windows 10 install and without a build environment) and there is a very little information on what might be going wrong with the library calls?
c000001d is illegal instruction exception code.
Either you are targeting instruction sets like AVX2 or SSE4.1 which the customer CPU doesn't support, or the executable is corrupted (e.g. downloaded in text mode instead of binary mode).
For best possible portability do not specify /arch:AVX or /arch:AVX2 when compiling with VC++. The compiler will then target the base instruction set available on the given architecture (x86 or x86_64 with SSE2).

Statically link with Microsoft CRT, and OpenMP

I’m developing some Windows software that's sometimes used in embedded-like scenarios. That’s not uncommon for my users to have a dedicated Win7 or Win8 PC they never update, not even connect to the Internet. Users plug those PC to a specific industrial hardware, and use that system for one job only.
My software includes components I've written in Visual C++. I include CRT in my MSI packages using appropriate installer merge modules.
Unfortunately, for a PC that never updated, that doesn’t work: today I got a bug report, the app crashes on startup saying “can’t start because api-ms-win-crt-stdio-l1-1-0.dll is missing from your computer”
This answer suggests static link to CRT.
Did that. But some parts of my C++ code rely on OpenMP for parallelism.
Dependency walker shows me the DLL I’m building depends on vcomp140.dll even when compiled with Multi-threaded (/MT) runtime library settings.
Also it shows vcomp140.dll only depends on kernel32.dll and user32.dll.
Can I just place that single DLL, vcomp140.dll, in the installation folder? Will it work on offline Windows 7 PC?
Based on the VS2015 Redistribution List I would say that copying that file would be indeed what you need to do and would work fine (if you used VS2015 to build your app). Take care to copy the proper dll based on arm/x86/x64.
Just to make it clear, it is not possible to statically link openmp with Visual Studio. Only two things you can do:
Remove openmp (and compile with /MT /MTd)
deploy vcomp140.dll (or VC redistributable) with your application

When do I need MSVCRT redistributables ?

I've built a MFC application in Visual studio 2010 and I'm scratching my head about including the redistributals in the installer.
The application is statically linked, so I should not need the redistributables, its selfcontained, right ?
Here is an an easy way to test if you need the redistributable:
Install a clean Windows 7 on a VirtualBox (or even better Windows XP SP 2, because it doesn't have the basic stuff you would expect)
Run your software on this VirtualBox
If it doesn't work, you probably need to include the redistributable.
Yes it should be OK but I would install on your intended target platforms and see if it works, if not then you would need to add more dlls or add as a pre-requisite to install the VC resdistributable before installing your app.
Although you may have included the MFC dlls, the Visual C runtime may be different on your target OS so you may still need to include the VC redistributable with you app.
MSDN link about doing the above: http://msdn.microsoft.com/en-us/library/ms235299.aspx and walkthrough: http://msdn.microsoft.com/en-us/library/dd293575.aspx
Any time you statically link a DLL or redistributable, you do not need to redistribute it. That's the core difference between static and dynamic linking.
It'll actually embed the parts you use (or the whole thing, depends) into your application. By redistributing your app, you are, in effect, redistributing its dependencies as well.
Note that you can't always use static linking and it doesn't always make sense to use it even when you can.

How to select against which version of the Visual C++ libraries the application is compiled?

I'm using Visual Studio 2008 for C++. When compiling, Visual Studio compiles against the header files of the VC 9.0 libraries. However, there are different versions of this library available:
v9.0.21022.8 (= RTM)
v9.0.30729.17 (= SP1)
v9.0.30729.4148 (= SP1 with security update)
I'd like to know whether it is possible to tell Visual Studio which version it should compile against.
The reason I think this is important is because the application's installer needs to make sure that the correct version of the Microsoft Visual C++ 2008 Redistributable Package is installed. To me it feels like I don't have any control over this dependency, as apparently some Windows Update (not a Visual Studio update) can change this dependency. I'd like to keep using the same version to avoid the overhead of making the installer upgrading the Redistributable Package.
Note that this situation is different from my earlier question, as that one was about link time. Neither am I looking for a way to control the version that is put in the embedded manifest file, as that is explained here.
The manifest that's included with your binaries is automatically generated by the VS build system. Important headers that determine the version dependency that's emitted into the manifest are vc\include\crtassem.h and crtdefs.h. The former declares the CRT version. Note that it already has support for the RTM version vs the "latest" version with the _BIND_TO_CURRENT_CRT_VERSION macro. The latter contains #pragma comment directives to embed the /manifestdependency linker option into the .obj file, which in turn makes the linker auto-generate the manifest.
You don't have to do it this way, you can simply turn off the linker options that generate the manifest and write your own. That gives you complete control over the CRT version that your app binds to. Whether you are ahead with this is a bit questionable. You would probably still be shipping the old version of the CRT that got updated in July of last year, it contained a critical security bug. Customers tend to be a bit unhappy about getting software installed on their machine that has well documented and solved security flaws.
The next thing you'd have to do is take control of the deployment of the DLLs. You'll have to deploy the DLLs into the WinSxS side-by-side cache yourself.
That will work, if you figure out how, but it isn't likely to survive for very long. Windows Update, if enabled, may discover that the machine is using an unpatched version of the DLLs and will update it. And deploy a publisher policy to redirect load requests. It is likely that your machine has such a policy file in place if you see your manifested version request resulting in the load of another version. The somewhat unescapable conclusion is that this is MSFT's DLL and they'll do with it what they think is necessary. Look at applocal deployment to avoid this.
It's this just a question of which directory your configuration is set to build against. As long as you have all the versions of headers on your machine and the libraries they link against I don't see why this can't be a new configuration for each version.
If the issue is things like SP1, there's not much you can do. Microsoft considers the runtime, in effect, a component of the operating system. It therefore gets updates and patches the same as any OS component.
There shouldn't be a problem with this, normally - the patches are bugfixes and security updates after all. In principle, each change should make your apps more stable. Not quite always true, but in any case there isn't much you can do about it.
There are options to change the runtime, but they are related to thread-safety and similar issues. There's a few relevant places in the project properties. In particular, in the C/C++/Code Generation tab you can select which run-time library to use.
If you are seriously worried, you can choose a statically linked non-DLL runtime. Users can still update their runtime DLL, but it won't improve the stability of your app when they do so.
You can do this using manifest resource files, which are written in XML.
We had to do this at a previous place of employment, unfortunately (or perhaps, more fortunately), I was not exposed to the in depth details of how it was done. This article looks about the closest to what we did that I could find on the subject.
Update0
Here is MSDN documentation regarding manifest file generation, and their use in isolating applications and building side by side assemblies.

Does the latest Visual Studio 2005 Security Update cause C runtime library issues when hot fixing customer sites

As you might be aware an update to visual studio 2005 was auto updated on most machines last week. This update included a new version of the visual c runtime library. As a result any binaries built after the update also require a new redistributable installed on client systems.
See http://support.microsoft.com/kb/971090/
And here is the installer for the new redistributable:
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=766a6af7-ec73-40ff-b072-9112bab119c2
This is fine for distributing new binaries to customers, I will ship the new redistributable with the installer and it will all work.
However I am really worried about my ability to hotfix existing customer sites if they discover a bug. In this case normally I would just send the dll or exe that was fixed.
However if I do this now, I will have to send these customers the new redistributable and now I will be using two different versions of the c runtime library in the same executable.
Is this a problem?
Can this cause my application to crash?
What happens if I allocate memory in one dll then deallocate it in another? Normally this works if the same release runtime library is used. I went through the our code about 3 years ago cleaning this up, but I cannot be sure that I have found and fixed all occurrences.
Is the allocate/deallocate in different dlls still a problem? Now that in the era of smart pointers etc it is very had to enforce this.
Can I control what runtime library version I depend on by changing manifests?
Any pointers or advice would be grateful.
Updated: I have just noticed this question
VC++: KB971090 and selecting Visual C Runtime DLL dependencies This is very similar, but my question is more concerned with using two different version of the runtime in one executable.
The version number specified in the application’s manifest file/resource only specifies the minimum version required to run the application. The default behavior of the loader is to first check the WINDOWS\WinSxS folder for the identical version or a superseding version of a dependency identified in an application manifest, and to use that version regardless of whether or not a private assembly containing the dependency has been provided with the application. (See http://msdn.microsoft.com/en-us/library/aa375674(VS.85).aspx).
So chances are your old binaries will also use the latest version of the Microsoft run time library anyway. Try to run the release build of your application (built before you update your Visual Studio) on a fully patched machine and use process explorer to see which DLLs it loads. The only problem is you will have to include the new run time redistributable file in your patch.
If you are still worried, you can try the method described here: http://tedwvc.wordpress.com/2009/08/10/avoiding-problems-with-vc2005-sp1-security-update-kb971090/
Yes you will not have to wait too much to see the problems using two runtime libraries.
If you allocate memory with a runtime and try to release it with another, your application will crash. It is and will continue being a problem.
Only the runtime what reserved the memory can track it. It is imposible for the other runtime to know how much memory you reserved.
You may want to read this, is a really good post about linking with msvcrt.dll.
I have heard (only by rumour) that if the manifest gives two versions of the CRT that only differ by minor revision number, then the application ends up only using the newer version at runtime. Ie, you do not run into problems with with multiple CRTs.
This is only rumour, and I'd love to hear a concrete answer on this.
See also: Visual Studio 2005 security updates and CRT DLL versions in manifest