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
Related
I'm trying to get a handle on which DLLs my native mode C++ win32 application uses. This isn't always obvious - I can link a library but it's somewhat more difficult to find out which system DLLs are needed, particularly if they're system DLLs.
As a case in point, I recently sent a test build to a remote member of my team who's running an older version of windows.
his machine complained about
'api-ms-win-core-misc-l1-1-0.dll' being missing (I assume this had something to do with my using 'GetSystemTime' and related functions but that's part of my problem: how do I tell?) but seeing as this is a windows system file, how can I package up an installer that will ensure these files are installed?
Also, I've used dependency walker and 'listdlls.exe' to find all the DLLs used by my program but dependency walker can't load that DLL and 'listdlls' seems to silently ignore it, so I can't find their location in order to redistribute them (which feels like the wrong approach anyway).
My question therefore is what's the current best practice to:
comprehensively determine all the system DLLs that are used by my
application
write an installer that ensures these libraries are
installed on a users machine
Find out which redistributable installers are needed from a given list of DLLS
I would have thought that installing a visual studio redistributable
package (e.g.
https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads)
would be enough. To my knowledge, the team member has installed this
but still gets DLL issues.
I have written a program in vc++14 that runs perfectly on my pc, both as a standalone executable, and debugging in visual studio 2015.
However, when I attempt to run it on a different pc, it stops responding immedietly. Using debug symbols, I have found any instantiation of classes via make_unique, or make_shared fails, causing null pointer exceptions.
I have checked and made sure that the target machine has the necessary vc++ runtime environments, and included any other dlls I can think of.
I have also tried statically linking the necessary libraries during builds, with no improvement.
I have even tried an installer project, which detected no additional dependancies.
I'm now at a loss. Is there anything else I should be looking for?
Verify following.
Ensure you’re building a release build. It’s relatively hard to make debug builds run on a PC that has no visual studio installed.
Ensure you have the exact version of vc++14 runtime, including the service pack number. If you’re using vs2015 update 3, download and install this on the target PC: https://www.microsoft.com/en-us/download/details.aspx?id=53587 (the correct platform, 32 or 64).
Ensure you don’t have anything funny in your preprocessor: that you don’t have _DEBUG, no _SECURE_SCL, etc.
P.S. A dynamic link to C runtime is not necessary a good idea for a release build. One problem, on some Windows versions, you can’t update CRT to the version you need even using an offline installer, because recent CRT depends on some Windows Updates.
I have been working on a VS 2005 project and have successfully generated an exe file which works fine on my system. However when I tried to run it on some other pc it didnt run. It throws up the error message "the system cannot run the specified program". Can someone tell me how to make my code immune to such message i.e. system independent?
platform used: Windows XP, VS 2005
the extension of all my code files is cpp but I know only c and thats what I wrote inside them.
I have seen before exe created on Windows Sp1 not working on SP2 and problems such as that.
This should help you perhaps.
I've seen this when you run on a different version of Windows that doesn't have some DLL you depend on. The easiest thing to do is statically link the C runtime (that's the usual culprit) and use depends.exe to see if there are any others.
You will almost certainly need to create an installer that installs your executable and any non-OS-included DLL's it relies upon. It is not always possible or desirable to statically link all dependencies. You can in many cases simply copy the DLL's to the same folder as the executable.
By default, even the C/C++ standard library is provided by a DLL. While the MSVCRT.DLL used by VC++ 6 is included with the OS since later editions Win95, the MSVCRT required by VS2005 is not included with XP installations (other versions I do not know). The run-time support is included VC redistributes package. You may need to arrange for your installer to include that installation, or you could be more selective is you know your dependencies.
Some Win32 API calls if you are using them are dependent on the OS version (check the documentation), but if you built and rin it on XP, it should normally work of any subsequent version of Windows. You need to define various API version macros if you want to extend support to earlier versions of Windows (which seems unlikley).
You might need to install the VS 2005 redistributables on the other machines, depending on how you have compiled your program.
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
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.