dll in c++, WINDOWS deployment / dependency's (mingw-w64 ) - c++

Background:
I'm programming a plugin (basically a dll) for an x64 application.
More specifically this x64 WIN application comes with a "plugin manager" (a dll) that loads and unloads 3rd party plugins (like mine).
My plugin is written in C++ and I decided to compile it with mingw-w64. As IDE I've choosen Code::Blocks.
I tried to avoid MS tools since later I need to deploy "the same" plugin on Linux and MAC (but that's another story lets focus on Windows for now).
Challenge:
There is one severe issue I can not resolve reliable with my knowledge/skill level, although I really worked hard in days of researches and tests: Dependency on WINDOWS dll's.
I must assure that this plugin runs on all WINDOWS versions from 7 to 10 (x64 only however).
The shipment of MS redistributables should be avoided since not practical in this case.
Apparently a static linking of the c-runtime library "MSVCRT.dll" seems to be neither allowed by copyright nor a reliable solution since there seam to be many different releases on the various WIN versions. Although Microsoft describes it as "known dll" I'm not sure which version is available where and which version is able to run on a certain Win version. And if a certain MSVCRT.dll runs, does it have enough "functionallity" for my plugin? (To high for me)
The question:
In your professional opinion what's is a reliable way to assure stability for my plugin on WINDOWS 7 to 10 (x64) in terms of Windows dll dependency's?
Are there other pitfalls I should worry about in the context of this dependency's on deployment.
Additional info:
Dependency walker_x64 (what a handy tool!) in this development stage of the plugin shows me dependency's on:
KERNEL32.DLL
MSVCRT.DLL (That's the guy I'm worried the most)
PM_64.DLL (That's the plugin manager of the x64 application)
On my computer (Windows 7 x64), MSVCRT.DLL shows version 7.0.7601.17744, OK, works. But if the customer has, say, a Windows 10 machine, freshly installed (not many MS redistributable versions available), will it work reliably?
I know that similar questions have been discussed before, especially on the c-runtime library "MSVCRT.dll". Many of them before WIN10 however.
The newlib idea (http://sourceware.org/newlib/) for example, 6years ago.
Mingw-w64 ships with archives called: libmsvcrt.a / libmsvcrtXXX.a. Is there a way with those?
I've read all I could find but I have to admit that now I have more doubts and questions than answers...
Your prefessional advice is appreciated. Thank you.

You may rely on presence and stability of at least the following dynamic libraries: kernel32.dll, msvcrt.dll, user32.dll, gdi32.dll. They are system libraries, present in C:\Windows\System32\ folder after the clean OS installation, and created by Microsoft as user API to interact with OS. MinGW library libmsvcrt.a (as well as non-static MS libraries) have no actual processing code but are just wrappers to call these DLLs from system folder.

Related

DLL hell and deployment: best practice for native windows applications

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.

VS2017 and missing "api-ms-win-core-rtlsupport-l1-2-0.dll" on Win7/XP

After porting some of my programs from VS2015 to VS2017 in noticed that the binaries no longer run on Windows 7 or Windows XP - even though they have been compiled with v141_xp toolset. The program fails to start with missing DLL api-ms-win-core-rtlsupport-l1-2-0.dll (note the 2).
I'm well aware that those api-ms-win-* DLL's belong to the UCRT and that, starting with VS2015, I have to redistribute the UCRT DLL's from the Windows 10 SDK (to be found at Redist\ucrt\DLLs in the Windows 10 SDK directory), along with my application - just redistributing the vcruntime140.dll and msvcp140.dll is not sufficient. But there is only api-ms-win-core-rtlsupport-l1-1-0.dll in my Windows SDK directory, but not api-ms-win-core-rtlsupport-l1-2-0.dll. I just downloaded and re-installed the latest Windows SDK (10.0.15063), just to be sure. Still the DLL in question is absent!
I also tried installing the VS2017 Redistributable package on the Windows 7 (or XP) machine via VC_redist.x86.exe - latest version downloaded from Visual Studio web-site (14.11.25325). Obviously that copies the api-ms-win-* DLL's into the "System32" directory. But, again, only api-ms-win-core-rtlsupport-l1-1-0.dll, but not api-ms-win-core-rtlsupport-l1-2-0.dll. App still won't start.
[EDIT]
This of course only applies if I link against the DLL runtime (/MD). If I link against the "static" runtime (/MT) I get a binary that has no DLL dependencies on UCRT and runs fine on Windows 7 and XP.
[EDIT #2]
Please refer to my other post (including EDIT) for the resolution of the mess:
https://stackoverflow.com/a/45773325/1766377
Okay, this is quite interesting: Just now my VS2017 found a new update. Apparently that updated my VS2017 from v15.2 to v15.3.1. The runtime libraries were updated as well, it seems!
There are now two directories, VC\Redist\MSVC\14.11.25325 and VC\Redist\MSVC\14.11.25415, inside my VS2017 install directory. The vcruntime140.dll exists in both directories. But the newer version (25415, right) has quite different dependencies, compared to the older one (25325, left):
 
Only the "new" version has dependencies that are missing on Windows 7. So, I should be fine going with the "old" version. But it means I'm locked to the "old" version. Is this normal / intended ???
(BTW: Both DLL versions from VS2017 v15.3.1 are newer than the one I originally took from v15.2)
[EDIT]
So, it was just brought to my attention that there is a subtle difference between the VC\Redist\MSVC\14.11.25325 and VC\Redist\MSVC\14.11.25415 directories: The 25415 directory has all DLL files inside another sub-folder called onecore, the other one doesn't. Apparently, this means that the "newer" DLL versions (the one with onecore sub-folder) are not supposed to be redistributed with normal Desktop applications; they are strictly for the "OneCore" Mobile/IoT platform.
Conclusion:
M$ did a great job to design the Redist directory structure as confusing as possible. Putting the version numbers of the "normal" and the "onecore" redistributables on the same level of the directory hierarchy (rather than having separate onecore and desktop directories on that level) indicates that those directories represent different versions of the same thing - which isn't the case at all :-/
Do *not* redistribute any */onecore/* DLL's with normal Desktop applications!
In the property pages for the project, try changing the Windows SDK version from 10.0.15063.0 to 10.0.10240.0. I think that will fix it, provided that the older SDK is installed on your build machine. Something else to try is to change the platform toolset to v140_xp. VS 2017 then builds with the VS 2015 tool chain, provided that VS 2015 is installed.
My personal preference is to avoid any 'DLL hell' by linking with the static runtime, although this won't work if an exe and a dll need to share a heap and incurs some space penalty if you are building several binaries (I just have two).

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

Are Visual C++ dynamic runtime libraries part of the Windows OS nowadays?

Are the dynamic runtime libraries for Visual C++ (more specifically 2008) part of the Windows OS nowadays? I noticed that at least on Windows 8 you no longer need to ship these with your application or have the user install the redistributable package from Microsoft.
Is this true? If so, for what Windows versions and for what versions of Visual C++ does this apply to?
No, they've never been part of the Windows distribution. Deploying them yourself is a hard requirement.
It certainly may seem that they are. Starting with msvcrt.dll in the system32 directory, it has the same name as the C++ runtime dll in Visual Studio versions prior to VS2002 (VS6 and earlier). It is however a private copy of the CRT that is used by Windows executables. And protected by the File System Protection feature in Windows, preventing old installers from destroying the operating system.
It certainly often works by accident. There are many programs that need the Microsoft CRT so it isn't unlikely that the user has run an installer before that got the DLLs installed. Clearly you cannot depend on that common accident.
Similarly for Windows 8, the pre-installed Microsoft.VCLibs.110 package matches the package you need for a Store app written in C++. But that's for the same reason as above, Microsoft Store programs were also built with VS2012, just like yours. What's going to happen in the upcoming VS2013 is a bit muddy right now, we'll know soon.
In my opinion, the answer would be both: Yes and No.
Yes: More recent Windows OS are generally shipped with VC runtimes pre-installed (along with more recent versions of the .NET framework). It is because Microsoft uses the latest/newer Visual Studio before they release VS to the public (or even to MSDN subscribers). If not this way, whenever you install some application (legacy application or some downloaded application), the setup would anyway install the required VC++ runtime. Another way is through automatic updates.
No: In case where none of the above mentioned rules applies. Or, when the VC runtime shipped with a new service pack or a patch. You might have developed your application with newer patch/SP, and that must be installed (as Side-by-Side, of course).

Want to run a program on some unknown system

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.