how-to: programmatic install on windows? - c++

Can anyone list the steps needed to programatically install an application on Windows. Aside from copying the files where they need to be, what are the additional steps needed so that your app will be a first-class citizen in Windows (i.e. show up in the programs list, uninstall list...etc.)
I tried to google this, but had no luck.
BTW: This is for an unmanaged c++ application (developed in Qt), so I'd rather not involve the .net framework if I don't have to.

I highly recommend NSIS. Open Source, very active development, and it's hard to match/beat its extensibility.
To add your program to the Add/Remove Programs (or Programs and Features) list, add the following reg keys:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PROGRAM_NAME]
"DisplayName"="PROGRAM_NAME"
"Publisher"="COMPANY_NAME"
"UninstallString"="PATH_TO_UNINSTALL_PROGRAM"
"DisplayIcon"="PATH_TO_ICON_FILE"
"DisplayVersion"="VERSION"
"InstallLocation"="PATH_TO_INSTALLATION_LOCATION"

I think the theme to the answers you'll see here is that you should use an installation program and that you should not write the installer yourself. Use one of the many installer-makers, such as Inno Setup, InstallSheild, or anything else someone recommends.
If you try to write the installer yourself, you'll probably do it wrong. This isn't a slight against you personally. It's just that there are a lot of little details that an installer should consider, and a lot of things that can go wrong, and if you want to write the installer yourself, you're just going to have to get all those things right. That means lots of research and lots of testing on your part. Save yourself the trouble.
Besides copying files, installation tasks vary quite a bit depending on what your program needs. Maybe you need to put an icon on the Start menu; an installer tool should have a way to make that happen very easily, automatically filling in the install location that the customer chose earlier in the installation, and maybe even choosing the right local language for the shortcut's label.
You might need to create registry entries, such as for file associations or licensing. Your installer tool should already have an easy way to specify what keys and values to create or modify.
You might need to register a COM server. That's a common enough action that your installer tool probably has a way of specifying that as part of the post-file-copy operation.
If there are some actions that your chosen installer tool doesn't already provide for, the tool will probably offer a way to add custom actions, perhaps through a scripting language, or perhaps through linking external code from a DLL you would write that gets included with your installer. Custom actions might include downloading an update from a specific Web site, sending e-mail, or taking an inventory of what other products from your company are already installed.
A couple of final things that an installer tool should provide are ways to apply upgrades to an existing installation, and a way to uninstall the program, undoing all those installation tasks (deleting files, restoring backups, unregistering COM servers, etc.).

I've used Inno Setup to package my software for C++. It's very simple compared to heavy duty solutions such at InstallShield. Everything can be contained in a single setup.exe without creating all these crazy batch scripts and so on.
Check it out here: http://www.jrsoftware.org/isinfo.php

It sounds like you need to check out the Windows Installer system. If you need the nitty-gritty, see the official documentation. For news, read the installer team's blog. Finally, since you're a programmer, you probably want to build the installer as a programmer would. WiX 3.0 is my tool of choice - open source code, from Microsoft to boot. Start with this tutorial on WiX. It's good.

The GUI for innosetup (highly recommended) is Istool
You can also use the MSI installer built into Visual Studio, it's a steeper learning curve (ie is a pain) but is useful if you are installing software in a corporate environment.

To have your program show up in the Start program menu,
You would need to create folder
C:\Documents and Settings\All Users\Start Menu\Programs
and added a short cut to the program you want to launch.
(If you want your application be listed
directly in the Start menu, or in the programs submenu,
you would put your short cut in the respective directory)
To programically create a short cut you can use IShellLink
(See MSDN article).
Since you want to uninstall, that gets a lot more involved because you don't want to simply go deleting DLLs or other common files without checking dependencies.
I would recommend using a setup/installation generator, especially nowadays with Vista being so persnickety, it is getting rather complicated to roll your own installation
if you need anything more than a single executable and a start menu shortcut.
I have been using Paquet Builder setup generator for several years now.
(The registered version includes uninstall).

You've already got the main steps. One you left out is to install on the Start Menu and provide an option to create a desktop and/or quick launch icon.
I would encourage you to look into using a setup program, as suggested by Jeremy.

Related

steps to make a registry-safe copy of an MFC COM project

I have tried several times in the past to make, say, a branch copy of MFC code which has a COM TypeLib. It has always been a registry nightmare. But the need is still there in that I want to be able to use an ordinary configuration management tool like SVN to make a branch so software can be delivered and development in the trunk can continue. COM and the registry have a hard time doing this for many reasons. What is needed is a list of vetted best-practice steps hammered out on a forum like this. Is there already experience out there? If not, is anyone interested in working with me on this? I have a starter list of steps.

How to add custom menu upon right click on file / folder programmatically in c++ / QT?

We have an app which syncs files and folder like the way dropbox does. This is an c++ / QT based installer.
We would like add custom menu in the right click context menu of a file or folder like the way dropbox does in the below screen shot.
We are targeting both windows & Mac platforms. Can anyone suggest me how to start with it?
On Mac, you're going to have problems as adding to the general Finder Context Menu has been deprecated.
So, you may be thinking, if it's deprecated, then how do Dropbox do this? From what I've researched in the past, I believe they use code injection to inject into the running Finder application's address space and then an Objective-C feature known as method swizzling to change calling a method to one of their own, which is located in the injected code.
This is all fairly hardcore and very low level, but if you're going to go on that journey, you can start by looking into a library called mach_inject and googling about it. The source code can be found here: -
https://github.com/rentzsch/mach_inject
However, be aware that there are those that believe code-injection is wrong and won't install Dropbox or any other software that uses it. In addition, if you're planning on releasing a product in the Mac Store, I wouldn't expect any application that performs code injection to be allowed.
For windows, I could find a complete Shell extension example over here.
http://www.codeproject.com/Articles/441/The-Complete-Idiot-s-Guide-to-Writing-Shell-Extens?fid=519&select=3236397&fr=76&df=90&mpp=25&noise=3&prof=True&sort=Position&view=None&spc=Relaxed

Which is the most appropriate way to find if a specific software is installed in Windows, using C++?

I'm writing a software that in a given moment needs to find if a given software is already installed (by its name) - so the same thing a installer does when it's going to installad its software and sometimes allerts that that software is already installed in the PC.
The problem is that I don't know which would be a good way of doing this. Now the softwares just looks to the default folder and if its unable to find the .exe, he then asks for the user to point out where he installed the software or else consider it uninstalled.
But I would like it to do things by its own; it should be capable of finding if a software is installed without user inputs, and I'm not sure which would be an efficient way of doing this.
The only way I found now is to do the same thing Windows' Add/Remove Programs does: look at many registry entries and try to found it, but I think this would take too much unacessary time give the fact it would look in many places to find only one software.
So isn't there any other less costful option in C++?
Thanks,
Momergil
This depends entirely on how the thing you want to ask about is installed. If it's always installed from an MSI, you can read up on MSI and learn to call the API and/or read the registry to see if its unique ID is there.
If it's installed with 'unzip', there's no concise solution.
what you are looking for is a key path: a registry location that is uniquely tied to that software.
You have two options:
A Registry key that is always present only when the software is installed.
eg. HKEY_CURRENT_USER\Software\BitTorrent\uTorrent
Look at the unique Uninstall entry of that software at: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall &
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
You will always find a REG_SZ here titled DisplayName which is used as the title in "Add Remove Software" Control Panel extension.
MsiGetProductInfo might get you the information you need, if you used Windows Installer.
If you didn't, well, then there's your problem... it's there for a reason.

Why should one use a build system over that which is included as part of an IDE?

I've heard more than one person say that if your build process is clicking the build button, than your build process is broken. Frequently this is accompanied with advice to use things like make, cmake, nmake, MSBuild, etc. What exactly do these tools offer that justifies manually maintaining a separate configuration file?
EDIT: I'm most interested in answers that would apply to a single developer working on a ~20k line C++ project, but I'm interested in the general case as well.
EDIT2: It doesn't look like there's one good answer to this question, so I've gone ahead and made it CW. In response to those talking about Continuous Integration, yes, I understand completely when you have many developers on a project having CI is nice. However, that's an advantage of CI, not of maintaining separate build scripts. They are orthogonal: For example, Team Foundation Build is a CI solution that uses Visual Studio's project files as it's configuration.
Aside from continuous integration needs which everyone else has already addressed, you may also simply want to automate some other aspects of your build process. Maybe it's something as simple as incrementing a version number on a production build, or running your unit tests, or resetting and verifying your test environment, or running FxCop or a custom script that automates a code review for corporate standards compliance. A build script is just a way to automate something in addition to your simple code compile. However, most of these sorts of things can also be accomplished via pre-compile/post-compile actions that nearly every modern IDE allows you to set up.
Truthfully, unless you have lots of developers committing to your source control system, or have lots of systems or applications relying on shared libraries and need to do CI, using a build script is probably overkill compared to simpler alternatives. But if you are in one of those aforementioned situations, a dedicated build server that pulls from source control and does automated builds should be an essential part of your team's arsenal, and the easiest way to set one up is to use make, MSBuild, Ant, etc.
One reason for using a build system that I'm surprised nobody else has mentioned is flexibility. In the past, I also used my IDE's built-in build system to compile my code. I ran into a big problem, however, when the IDE I was using was discontinued. My ability to compile my code was tied to my IDE, so I was forced to re-do my entire build system. The second time around, though, I didn't make the same mistake. I implemented my build system via makefiles so that I could switch compilers and IDEs at will without needing to re-implement the build system yet again.
I encountered a similar problem at work. We had an in-house utility that was built as a Visual Studio project. It's a fairly simple utility and hasn't needed updating for years, but we recently found a rare bug that needed fixing. To our dismay, we found out that the utility was built using a version of Visual Studio that was 5-6 versions older than what we currently have. The new VS wouldn't read the old-version project file correctly, and we had to re-create the project from scratch. Even though we were still using the same IDE, version differences broke our build system.
When you use a separate build system, you are completely in control of it. Changing IDEs or versions of IDEs won't break anything. If your build system is based on an open-source tool like make, you also don't have to worry about your build tools being discontinued or abandoned because you can always re-build them from source (plus fix bugs) if needed. Relying on your IDE's build system introduces a single point of failure (especially on platforms like Visual Studio that also integrate the compiler), and in my mind that's been enough of a reason for me to separate my build system and IDE.
On a more philosophical level, I'm a firm believer that it's not a good thing to automate away something that you don't understand. It's good to use automation to make yourself more productive, but only if you have a firm understanding of what's going on under the hood (so that you're not stuck when the automation breaks, if for no other reason). I used my IDE's built-in build system when I first started programming because it was easy and automatic. I later started to become more aware that I didn't really understand what was happening when I clicked the "compile" button. I did a little reading and started to put together a simple build script from scratch, comparing my output to that of the IDE's build system. After a while I realized that I now had the power to do all sorts of things that were difficult or impossible through the IDE. Customizing the compiler's command-line options beyond what the IDE provided, I was able to produce a smaller, slightly faster output. More importantly, I became a better programmer by having real knowledge of the entire development process from writing code all the way down through the generation of machine language. Understanding and controlling the entire end-to-end process allows me to optimize and customize all of it to the needs of whatever project I'm currently working on.
If you have a hands-off, continuous integration build process it's going to be driven by an Ant or make-style script. Your CI process will check the code out of version control when changes are detected onto a separate build machine, compile, test, package, deploy, and create a summary report.
Let's say you have 5 people working on the same set of code. Each of of those 5 people are making updates to the same set of files. Now you may click the build button and you know that you're code works, but what about when you integrate it with everyone else. The only you'll know is that if you get everyone else's and try. This is easy every once in a while, but it quickly becomes tiresome to do this over and over again.
With a build server that does it automatically, it checks if the code compiles for everyone all the time. Everyone always knows if the something is wrong with the build, and what the problem is, and no one has to do any work to figure it out. Small things add up, it may take a couple of minutes to pull down the latest code and try and compile it, but doing that 10-20 times a day quickly becomes a waste of time, especially if you have multiple people doing it. Sure you can get by without it, but it is so much easier to let an automated process do the same thing over and over again, then having a real person do it.
Here's another cool thing too. Our process is setup to test all the sql scripts as well. Can't do that with pressing the build button. It reloads snapshots of all the databases it needs to apply patches to and runs them to make sure that they all work, and run in the order they are supposed to. The build server is also smart enough to run all the unit tests/automation tests and return the results. Making sure it can compile is fine, but with an automation server, it can handle many many steps automatically that would take a person maybe an hour to do.
Taking this a step further, if you have an automated deployment process along with the build server, the deployment is automatic. Anyone who can press a button to run the process and deploy can move code to qa or production. This means that a programmer doesn't have to spend time doing it manually, which is error prone. When we didn't have the process, it was always a crap shoot as to whether or not everything would be installed correctly, and generally it was a network admin or a programmer who had to do it, because they had to know how to configure IIS and move the files. Now even our most junior qa person can refresh the server, because all they need to know is what button to push.
the IDE build systems I've used are all usable from things like Automated Build / CI tools so there is no need to have a separate build script as such.
However on top of that build system you need to automate testing, versioning, source control tagging, and deployment (and anything else you need to release your product).
So you create scripts that extend your IDE build and do the extras.
One practical reason why IDE-managed build descriptions are not always ideal has to do with version control and the need to integrate with changes made by other developers (ie. merge).
If your IDE uses a single flat file, it can be very hard (if not impossible) to merge two project files into one. It may be using a text-based format, like XML, but XML it notoriously hard with standard diff/merge tools. Just the fact that people are using a GUI to make edits makes it more likely that you end up with unnecessary changes in the project files.
With distributed, smaller build scripts (CMake files, Makefiles, etc.), it can be easier to reconcile changes to project structure just like you would merge two source files. Some people prefer IDE project generation (using CMake, for example) for this reason, even if everyone is working with the same tools on the same platform.

Where should my win32 program keep its files?

Our win32 applications (written in C++) have been around for over 10 years, and haven't been updated to follow "good practices" in terms of where they keep files. The application defaults to installing in the "C:\AppName" folder, and keeps application-generated files, configuration files, downloaded files, and saved user documents in subfolders of that folder.
Presumably, it's "best practices" to default to installing under "c:\Program Files\AppName" nowadays. But if we do that, where should we keep the rest of our files? Starting from Vista, writing to the program files folder is problematic, and there seem to be a million other places that you can put different files, and I'm confused.
Is there a reference somewhere for what goes where?
Edit: To expand on questions people have asked so far:
I'm familiar with the SHGetFolderPath function, but there are lots and lots of options that you can get from it, and I can't find a resource that says "Here is exactly what each of these options is used for, and when you might want to use it".
Up until now, we've done the "All files, including saved user files, under one folder" thing, and it's worked fine - but not when people want to install the app under the Program Files folder. For some reason, the virtualization monkeying around that Vista does isn't working for our application; if we're going to be making changes anyway, we might as well make an effort to do things the "right" way, since we don't want to have to change it again in 12 months time.
Further question:
We include some "sample" documents with our app, which we update every now and again. Is it appropriate to install them into My Documents, if we'll be overwriting them every few months? Or is My Documents assumed to be totally safe for users to mess around in?
If we can't install them to My Documents, where should we put them so that users can see them easily?
Presumably, it's "best practices" to default to installing under "c:\Program Files\AppName"
Close, but not quite. Users can configure the name of the Program Files folder and may not even have a C: drive. Instead, install to the %ProgramFiles%\AppName environment variable folder.
Note you should assume you only have read access to this folder after the installation has finished. For program data files where you might need write access, use %AppData%\AppName.
Finally, are you sure yours is the only app with that name? If you're not 100% certain of that, you might want to include your company name in there as well.
The mechanisms you use to retrieve those variables will vary depending on your programming platform. It normally comes down to the SHGetFolderPath() Win32 method in the end, but different platforms like Java or .Net may provide simpler abstractions as well.
Some guidelines are in this Knowledge Base article: How to write a Windows XP Application that stores user and application data in the correct location by using Visual C++. Also, if you search MSDN for Windows Logo Program you will find documentation regarding what an app needs to do to be truly compliant.
SHGetKnownFolderPath can get you the directories you need. If backwards compatibility with XP and earlier is required, use the deprecated SHGetFolderPath
Having said that, if you app came with documentation that said "everything used by this app is in this directory" I would love it ;)
Use the Windows SHGetFolderPath() function to get the correct directories.
Edit: To reply to your other question, added in the edit: Where to put the sample files of your application does very much depend on whether your application is installed for a single user or for all users, and whether the person installing the application can be assumed to be the one who uses it.
If your program is to be used by multiple users on a system, copying stuff into "My Documents" is not going to work - the files would be accessible only for the user installing the application. Worse, if the only user of your application needed to install as Administrator, then [s]he will not have access to the files either. So unless you are fairly certain that there is only one user for your application, and they have sufficient permissions to install the application using their own account, don't use "My Documents".
IMO you should install sample files into the directory identified by CSIDL_COMMON_APPDATA. This will give you exactly one copy for all users, and since you want every user to see the original, unaltered sample files all users should consider them read-only. In fact, your setup program should probably make them read-only. Opening one of the samples will work for all users, but as soon as they try to save their modifications the application should detect that the file is read-only, and open the "Save As" dialog, pointing to "My Documents" or suitable directory inside. That will also keep all user modifications when the installer updates the sample files later on.
It is of course somewhat more difficult for the users to find the sample files. You could add a link to the samples folder to the start menu group of your application, so that access to the files is fast, and of course you should properly document everything.
For your application binaries, you can assume that you may write to the PROGRAM FILES directory (use the %ProgramFiles% environment variable to support installations other than the default English version - e.g. in german Installations this will be c:\Programme by default). Wikipedia lists the most common variables. Another option are the SHGetFolderPath or newer SHGetKnownFolderPath functions.
For User data, you should assume that the application is running with limited access rights and may only write to the user's home directory. Same applies for registry entries. This path should probably be configurable b the user, as the home directory may actually be a network server and a user might have a second disk attached for data storage. For information on the current (Vista) filesystem guidelines see this article.
Regarding plugins, this might be more complicated. The best practice seams to be offering the option to install for the current user only, and placing the plugin in the user directory, or install for all users and place the files into your program files directory (but remember to check for write permission and request elavated access if needed).
There are plenty of environment variables like: %USERPROFILE%, %HOMEPATH%, %APPDATA% all of these points to some user-specific directories, where you can put your user-specific files.
For system-wide storage you can use %ALLUSERSPROFILE%, that is the place where you should put your read/write datafiles that are not specific to any user.
Sorry I don't know the correct answer, but...
Do you have a business case for wanting to do that? Are your customers complaining that files aren't stored where they expect? Are your applications crippled in some way because you store files in non-standard locations? If not, I don't see a reason for spending time and budget to redo your file storage strategy just to meet "best" practice. If your programs just work, then IMHO you should leave them alone and spend money and time on things that matter.
There is a directory structure under c:\users for user oriented data.
There is documentation for porting apps from older windows OSs to Vista.
Check out http://www.innovateon.com and follow the links to Vista. There is documentation regarding certification that has the details on topics like this.
We have a similar app created ~10 years ago using MFC. The easiest thing to do was create a folder right off of C:\ (e.g. C:\OurApp). No install files, no special permissions, no registry changes, etc. Clients (and particularly their sys admins) LOVE it.
One other consideration - are you planning to all of a sudden change the installation folder for existing clients (assuming this is installed in many locations)? If something isn't broke, why fix it?