Detect if an assembly is available - c++

I'm implementing an installer in Java, that is supposed to download and install an application for non-privileged users in Windows (from XP and up). The application is written in C++, and depend on the usual VC runtime-libraries (msvcm90.dll and friends). In order to save bandwidth, I want to avoid downloading the VC redistributables if they already are available for the user. I do however have a problem finding a reliable method to detect if an assembly is installed.
If the assembly is missing, I will deploy it as described here:
http://msdn.microsoft.com/en-us/library/ms235291%28VS.80%29.aspx
So the question is simply how to detect if a (any) assembly is installed on the machine. It's no requirement that this can be done from Java. I can easily write a small probe in C++ and link it statically for the task.
jgaa

If you are willing to write a small test program, then rather than writing one that looks for your dependencies, write one that has the same dependencies as your application. Try to run it. If it runs, the dependencies are in place. If it fails, the probable reason is that the dependencies are missing.

Seems a fairly complicated trick really as depending on the setup these may already be located in several possible places. Perhaps your best bet would be testing for the existence of these DLL's using the WinAPI LoadLibrary - this should find any DLL that is shared and appropriate to the build automatically.
Even better LoadLibrary a DLL that requires them as Ben suggests.

Related

Qt Application : How to create standalone executable file for Windows (& Mac) from Mac?

I developed a Qt application in MacBook (El-Capitan 10.11.2) and it is ready now to be released.
What i want now, is to create the standalone executable file for both Mac and Windows OS.
But I don't know how !
I found this link but I am unable to follow it is guidance, it looks different from what my system is showing me.
If you have any idea, please help me.
Thank you
Well, to compile an application for windows, you will need a windows machine (or at least a virtual machine). You can't compile for windows on mac.
Regarding the "standalone": The easy way is to deploy your application together with all the required dlls/frameworks and ship them as one "package". To to this, there are the tools windeployqt and macdeployqt. However, those will not be "single file" applications, but rather a collection of files.
If you want to have one single file, you will have to build Qt statically! You can to this, but you will have to do it on your own. And if you do, please notice that the LGPL-license (the one for the free version of Qt) requires you to make the source-code of your program public! That's not the case if you just link to the dynamic libraries.
EDIT:
Deployment
Deployment can be really hard, because you have to do it differently for each platform. Most times you will have 3 steps
Dependency resolving: In this step, you collect all the exectuables/lirabries/translations/... your application requires and collect them somewhere they can find each other. For windows and mac, this can be done using the tools I mentioned above.
Installation: Here you will have to create some kind of "installer". The easiest way is to create a zip-file that contains everyhing you need. But if you want to have a "nice" installation, you will have to create proper "installers" for each platform. (One of many possibilities is the Qt Installer Framework. Best thing about it: It's cross platform.)
Distribution: Distribution is how to get your program to the user. On Mac, you will have the App-Store, for windows you don't. Best way is to provide the download on a website created for this (like sourceforge, github, ...)
I can help you with the first step, but for the second step you will have to research the possibilities and decide for a way to do it.
Dependencies
Resolving the dependencies can be done by either building Qt statically (this way you will have only one single file, but gain additional work because you will have to compile Qt) or using the dynamic build. For the dynamic build, Qt will help you to resolve the dependencies:
macdeployqt is rather easy to use. Compile your app in release mode and call <qt_install_dir>/bin/macdeployqt <path_to_your_bundle>/<bundle>.app. After thats done, all Qt libraries are stored inside the <bundle>.app folder.
For windeployqt is basically the same: <qt_install_dir>\bin\windeployqt --release <path_to_your_build>\<application>.exe. All dependencies will be inside the build folder. (Hint: copy the <application>.exe in an empty directoy and run windeployqt on that path instead. This way you get rid of all the build-files).
Regarding the static build: Just google it, you will find hundreds of explanations for any platform. But unless you have no other choice but to use one single file (for whatever reason) it would recommend you to use dynamic builds. And regarding the user experience: On mac, they won't notice a difference, since in both cases everything will be hidden inside the app bundle. On windows, it's normal to have multiple files, so no one will bother. (And if you create an installer for windows, just make sure to add a desktop shortcut. This way the user will to have "a single file" to click.)

How should/could/must I handle the dll that my C++ projects depend on?

I'm lost here and I have no clue how to proceed. This is not a question about how to make my program work, this is a question about how to stop wasting my time.
My programming environment is Visual Studio 2013 on windows, in C++.
I use 3 libraries extensively, namely: boost (using dynamic linking), OpenCV, and Qt.
During the development, I have configured VS to look at those 3 libraries by default for include and .lib. I have also added the 3 folders containing all the dlls to my PATH environment variable.
It works, but it is sometime painful, let me explain you when.
First hassle: Anytime I have a LNK error telling me I miss a function, it is usually on OpenCV since it has only one include file referencing all the functions. I have to look at OpenCV's source code to see what module this function belongs to and to know what I must link my program to.
Second Hassle: When comes the time to deploy my application, I have to ship it with all the relevant dlls. To know which one I need, I open dependency walker and try to forget nothing, I have then to test it on a different computer because 102% of the time I have missed a couple, and then I have to configure my Installer generator to include all those one by one.
Third Hassle: To ease a little bit the process of configuring a new development machine, I have recently switched to NuGet. It is great, I add boost with a couple of clicks to any project. But now my boost DLLs are everywhere, I have one folder per boost library, and since there are dozens of those I can't even add them all at once to my PATH now, so I have to move them manually to the appropriate folder, and that is really not what I want to do with my not-so-precious-but-who-are-you-to-judge time
I have looked around and couldn't find any good practice regarding this issue, maybe because they are too obvious, or too specific to a particular setup.
How do you do? How would you do if you were me?
We put all our external dependencies in version control along with the code. This ensures that all code can build "out of the box" on any of our development machines and also ensures that for any given version of the code, we know exactly which dependencies is has.
The best way to check for missing dependencies is how have a good automated test suite, if you've got comprehensive converge then if your tests pass you must have deployed the required libraries.
In terms of linking to the appropriate libraries, unfortunately, that just sounds like an issue with the structure of OpenCV (I'm not familiar with OpenCV). I tend to use dumpbin under Windows and nm under Linux to easily grep for symbols when I get link errors with an unfamiliar library.

What is the important dll files to execute any Qt5 application on any platform (Runtime files dll)?

I have created a simple application in Qt5 but, when run that application in for example windows 7, tells me the dll file something is missing, and another dll and another dll.
Now I want a package that contain all dll files that any Qt application needed.
Or, What's the Important dll files that needed to work any Qt application ?
Or, What's the Important dll files that needed to work any Qt application ?
In general, the Qt modules that you are using. If you use QtSql, you need to have the corresponding dll, but it goes the same way for any module. As for a simple core application, you would need to have the QtCore dll, respectively. I could continue the enumeration, but I believe you see the pattern how it goes.
Going even a bit further, you would need to specify your dependencies in the LIBS variable if you happen to use qmake. That is also a place where you would already need to be aware of your direct dependencies.
It would be usually the single library name, but in complex cases, you can always read the documentation of the project. The main point is the fact that you need to get aware of this without debugging. The latter would be more like an after-thought.
There are no "hidden dependencies". Since you are coding the project, you know the dependencies that you use. You will need to ship them.
There are some odd and rare cases when issues come that you would not be aware of, like missing dll for a different machine having a distinct VS/MSVC setup. In that case, it is better not to ship all the dlls for each possible end machine, but the end machine is supposed to install redistributable packages.
In rare cases when the above does not suffice, you can check the error message. If that is still unclear, you can use introspection tools for debugging the issue, like dependency walker.
Disclaimer: this answer goes as broad as the question is.

How to deploy a portable C++ application?

I have written a portable C++ application using Qt libraries. This means that I cannot use the MT flag for compiling without risking memory issues.
This leaves me with two options:
1) Deploy the portable application with an installer.
2) Package the C++ dependencies within the same folder or use private assemblies.
Both 1 and 2 defeat the idea of portable software, so I was thinking of a third option:
3) Use IExpress to drop the C++ dependencies before launching the application. On exit, delete the C++ dependencies.
Unfortunately, option 3 has received some flak from some stackoverflow members. They even dislike option 2 which leaves me with only option 1. I can see option 1 as doable if I use a portable installer.
Is there such thing as a portable installer? Essentially, I want the installer to check to see if the needed dependencies are installed before running my application (just like a regular installer would) and if they are, then just continue running my application. Otherwise, give a message box to the user that they could download it providing a link to the URL. I am aware I can write my own installer that can do this in C++ but I was wondering if there are any installers that already offer this specific functionality.
http://qt-project.org/doc/qt-4.8/deployment.html
The dlls for Qt in windows are so small, that deploying them with the application isn't an issue in my opinion.
There aren't any programs out there that I know of that place the Qt dlls on windows in some place that another program later would find (like c:/Windows/system32).
I think the only place where you could expect reuse of the libraries is in Linux or a mobile device that has a lot of Qt apps. But even then you have make sure that the versions of the libraries are high enough to support all the functionality that you are using.
Hope that helps.

Requirements for shipping runtime libraries/DLLs

I have read these two SO questions: Which runtime libraries to ship? and License of runtime libraries included in GCC? - both were very helpful but not quite what I was looking for.
I have always just written programs for use on my own machine, which has never caused me any problems, but now I want to start running software on other machines and I'm wary of the runtime requirements.
EDIT: See below example instead, this was misleading.
Specifically, if I write a C++ program on a Windows machine, compiled with gcc through MinGW, and want to run it on another machine:
Do I have to send the libstdc++.dll with my program?
Is this single file (I assume placed in the executable's directory) sufficient to allow the program to run?
Also, an identical example, except this time it is an Objective-C program. Is sending the libobjc.dll file to the other machine sufficient to allow the program to execute properly?
I am used to running programs on machines which have developer tools, etc, installed, but now I'm looking to run them on general purpose machines (friends', colleagues' etc), and I'm not quite sure what to do!
EDIT: In response to edifice's answer, I feel I should clarify what it is I'm looking for. I know how to identify the necessary DLL(s) (/dylibs, etc) that my programs use, (although I am accustomed to doing that work manually; I had not heard of any of the tools). My question was more "What do I do now?"
A more general example is probably needed:
Let's say I have written a program which has object files derived from C++, C and/or Objective-C(2) code. I have used some Windows API code which compiled successfully using MinGW's gcc. I also have a custom DLL I wrote in Visual Studio (C++).
I have identified which DLL's my program will use at runtime (one of which may be GCC's libobjc.dll, I'm not sure if this would/should make a difference on a Windows machine, but I want to make this as general as possible) - The "prerequisite DLLs".
I would like to run it on my colleagues' computers, most of which run Windows 7, but some now run Windows 8. Starting at the very start for the sake of completeness:
Do I need to transfer the prerequisite DLLs to my colleagues' computers?
What directory should I place them in? (exe directory / a system directory?)
Once in place, will the presence of these DLLs allow the program to execute correctly? (Assuming it knows where to find them)
Are there any other files that should be transferred with the DLLs?
Basically I'm trying to determine the entire thought-process for developing and running an application on another machine in terms of system runtime requirements.
When loading DLLs, the first place Windows looks is the directory that the exe is in. So it will probably work just fine to put the DLLs there.
For the Microsoft DLLs though, I think it makes more sense to ask your colleague to install the Visual C++ runtime, which is a redistributable package from Microsoft. Ideally you would make an installer using something like WiX and it would install that prerequisite for you, but it is OK to just tell your colleague to do it.
Be sure to include a license file with your software if you include DLLs from gcc, because the GPL requires it.
libstdc++ isn't necessarily sufficient. You almost certainly need libgcc too, but actual dependencies are liable to vary with your particular application.
The best way to determine what you need to ship with your application is to load your EXE into a program like Dependency Walker.
Just as an example, I've compiled a test C++ program which simply prints a std::string. As you can see, it depends directly on two modules other than those that come with Windows; libgcc_s_dw2-1.dll in addition to libstdc++-6.dll.
You should remember to expand the tree under each DLL to make sure that it itself doesn't have any other dependencies (if A depends on B, B might depend on C even if A doesn't directly depend on C).
If you're worried and want the strongest assurances, you could install Windows into a virtual machine (VirtualBox is free) and test your application inside it. If you use Microsoft APIs, you may wish to check the MSDN documentation to see with what version of Windows they were introduced and ensure that it aligns with your target minimum Windows version.
Update: As xtofl points out this won't cover libraries loaded dynamically using LoadLibrary. If you want to cover this base, use Process Monitor to examine what DLL files are touched when you run the application. (Add an 'Image Path' criterion with the path to your EXE in order not to get flooded.) This has the added advantage that it covers all files, registry entries, etc. that your application depends on, not just DLLs.