Installing multiple MSI's dynamically Visual Studio C# - c#

I have three windows based application. I need to deploy them into a single msi file. The first two files are kinda like the check for the proper computer, like the specific computer name and login username. The problem I have is that how can I deploy all these three application into one msi file. And the installation goes like this ?:
1: Install the window application A
2: If application doesn't install properly then stop installation and delete application B and application C. However if everything goes fine then install the final main application, Application C.
Addition information: The application A and Application B is basically kinda checking the username and proper name of the computer and then printing out the specified values into the registry.
Appreciate help in advance :)

If you're using the VS Setup Project installer, this is a little more difficult than it has to be but not by much.
The first thing you should do is pick a "primary" application. This application's installer will be the one invoked by the user to install all three and will control the other two.
Now, deploy the other two applications into their MSI files. This process is relatively straightforward; the only thing you must do is ensure that any custom information that may be needed by the setup wizard can be defined using command-line parameters, and that the installation can be performed in an unattended manner. VS Setup Projects allow both of these; you have to define the parameter name of any custom field in your wizard, but given that the unattended feature is "free". Once these MSIs are built, add them as files to be installed to the main application directory of the primary app.
Now, you must define custom actions in the installer of the primary application. This is done by creating a class inheriting from System.Configuration.Install.Installer, decorating it with a RunInstaller attribute, and specifying this Installer class's project as a set of Custom Actions for the installer.
In the Installer class, override the OnAfterInstall, OnBeforeUninstall, and OnRollback methods. In the OnAfterInstall method, call Process.Start to invoke MsiExec.exe with the /I option to install, passing the path and name of the first application's MSI, and specifying the "/q" option to perform the install silently as well as any properties which must be set (installation parameters; path, install level/components, app settings, etc). Repeat for the other application, then repeat the process with the OnBeforeUninstall and OnRollback methods, but specifying the /x option to uninstall the MSIs.
When you're done, you should have a single MSI containing the other two MSIs, that when installed will silently install the other two and when uninstalled will uninstall the other two. For more advanced installation control, you can differentiate between an "install" and a "modification/repair" by examining the savedState dictionary in the handlers (during a repair, you should repair the child apps instead of trying to reinstall them), and you may make installation of the other two applications optional using a Components dialog in the install process (the information will be passed to the custom action handlers, and can also be used to choose whether to copy one or both MSIs to the primary app directory). Finally, you may choose to override OnAfterCommit and remove the MSIs (but if you do so, you will have to uninstall the child packages using Windows' retained copy of the MSI, which can be tricky to find).

Related

Detect All Users .msi

I wrote a C# program in Visual Studio that uses the Setup & Deployment Project to create an .msi installer. The "InstallAllUsers" value is set to "True", so it'll install "Everyone" by default, but the users can change it to "Just Me" during setup.
It's just a basic installer - nothing fancy.
My question is this: after they install the program, is there a way to tell which option they chose? Is there a registry key that I can dig for that will tell me whether they chose "Everyone" or "Just Me" during install? I'm not programmatically adding any registry keys, and I can find the "Uninstall" key for my program, but I don't know if there's a value in there that will tell me.
* EDIT *
For a clearer picture:
As I make changes to my program, I increment the version numbers and give the updated .msi to the users, and they just rerun the installer. There was originally only supposed to be a couple of users, so I didn't make a complicated updater. Now there are many users, and the updater is in-the-works. For now, the current users are happy with the process - I give them a new .msi and they run it again - except for one thing: the installer doesn't "remember" their settings from the last time they ran the installer (their words, not mine). I can get the directory of their last install from the "Uninstall" regisrty value and set it with TARGETDIR, so I've got the installation path covered. But I'm trying to figure out if the user changed "Everyone" to "Just Me" the last time around.
One way could be check for current logged in user in registry and see if it has the software listed in in installed software list under HKEY_CURRENT_USER\SOFTWARE\*
There's an example here of enumerating products to find out which context they were installed in. If you know the ProductCode you can just do the MsiGetProductInfo part.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa368279(v=vs.85).aspx
There are APIs for this, so it is more advisable than guessing based on what might be in the registry.
The installation folder properties window in Visual Studio setup projects has an InstallAllUsersVisible property you should set to False. Otherwise it's going to be a nightmare when you do an upgrade with RemoveExistingProducts=True because that requires the upgrade to be in the same context as the original install. You'll find people trying to do an upgrade with All users of an installed Just me product and it will not work.
I don't like per-user installs due to all the problems relating to upgrades, patching, etc... Accordingly I managed to migrate per-user installs to a per-machine during a major update install using Installshield and their built-in ISSetAllUsers custom action plus some re-sequencing of various standard actions. The description can be found here: windows Installer - uninstalling previous version when the versions differ in installation policy (per-user, per-machine)
If you want to migrate all installs to a per-machine install, you could replicate this approach using Phils suggestion to read the current installation context via your own custom action and then run this custom action in place of the ISSetAllUsers custom action that Installshield provides. Then you can follow the rest of the procedure from the link above.

Creating a Setup Project for multiple applications in Visual Studio

Suppose I have two application - App A and App B which are already created and are working fine. Now I want to create a new setup project which can be used to create a setup file for both of the applications. Can this be possible of creating a setup file for installing both apps? Also I want to perform the installation in such a way that - once the App A is installed then only the installation of App B should begin.
Thanks.
With VS setup projects you can create one setup (I assume you mean an MSI setup and not ClickOnce) that contains "everything" from both apps - the files, the shortcuts, dependencies etc. Then you will have a single setup that will install and give you one entry in Programs&Features. There's often no need to have a "A must install ok before B installs" because that single combined setup is transactional, like all MSI installs - if anything fails then the entire install rolls back.
If A just contains functionality that happens to be packaged as an MSI that B and other products are going to use, then sometimes people just build A as a merge module and include it into B (and the other setups) but that depends on why there are two setups and the business/workflow requirements.
There's no VS support for combinining separate MSI files into one setup and conditioning B on the success of A. You may as well just write a launcher that runs both MSIs, but you'll see two sets of UI and two entries in Programs&Features, but you don't say if these are things you want to avoid or not. Obviously if B depends on A and there are two entries in Programns&Features it's possible a user could uninstall A and break B.
The main issue is whether you just want a launcher that will install some number of MSI files each with their own UI and entry in Programs&Features, or you want an integrated experience that makes multiple MSI files install and uninstall as a single product.
Apart from that, I've known people build their MSI files with something like VS and then use the WiX Burn bootstrapper to combine them into one product, where the Programs&Features entry combines all the MSI files.
There used to be the Bootstrap Manifest Generator tool that would let you add A as a prerequisite so setup.exe would install prerequisites, including A, and then install B, but that tool and its docs are hard to find since setup projects got taken away in VS 2012.

Setup project modificatios

I have made a application using c# database and sucessfully made a setup projects that outputs setup files needed to install that application but when i install it on other machine first I have to update installer then framework 2 sp2 and then SQL server and when I tell my client that he would have to do the same he just ........... so I want a way to embed these things in that installer wizard so that in a one go every thing gets installed without prompting for each thing . for example when we install visual studio every thing gets installed without asking permission as we select what to install.so is there a way?
If you have a setup wizard for each of the parts you need to install, you may want to take a look at Inno Setup, as you can embed those installers in a new one which in turns executes Database/.NET Framework/application setups in correct order to properly configure all the pieces of the solution on a machine.
As setup applications usually have a way to configure options by command line parameters and run silently, you can collect all parameters you need in the new wizard page and call any of the needed installers just by adding a line in the [Run] section of the script.
With Inno you can even embed a pascal script to run code at wizard run-time, for example to inspect destination machine in order to run or not run some installers. You are able to download required extra-files on demand also.
When you compile a Inno setup project with default options, you get a single executable containing all what you need to install your project, making deployment very easy.
This options may be available for the tool you're using now to produce your installer.

Why the shortcut created by my MSI install start the setup process again each time?

I created my MSI installer for our C# application via VS 2008. I installed it. It created a shortcut for me on the desktop. I clicked that shortcut, the setup process running again and at the end our application was launched. It was not like this yesterday before I added some custom action to create database. I didn't recreate the shortcut in the installer. why it is like this?
Open the MSI manually using Orca. Add the following record to the Property table (Property, Value) without the quotes:
Property = 'DISABLEADVTSHORTCUTS'
Value = '1'
This can also be scripted and run as part of a post build event.
MSI comes with an auto-repair feature that checks whether all components installed by MSI are still present when you launch your application using the shortcut.
In your case, probably one (or more) components have been removed so the installer is launched again to repair your installation.
To prevent auto-repair from running either
Make sure no file, registry setting or other installed component is removed
or
Don't set the key path for those components. That will prevent MSI from checking those specific components
From your other questions it seems that your MSI has been created by a Visual Studio Setup and Deployment Project. Unfortunately, there is no option to modify the key path from within Visual Studio. You have the following options:
Modify the MSI manually using Orca (This is not a good option because it is a manual step)
Write a script e.g. using VBScript to patch the MSI file
Move to a more advanced install system which gives you more control such as WiX or NSIS
Is the shortcut pointing to your application or your setup? If it's pointed to your setup and you change it to your application, does the problem go away?
Sounds like the system thinks the installation has been corrupted and is automatically attempting a repair,.Anything in the event logs (look for source of MsiInstaller in the Application Event log).
Have you been building multiple copies?
This happens when the application deletes a file that was deployed during the installation. The Auto-Repair is activated and hence you get the installation screen.
Had the same problem. In my case it turned out the issue was 'Manufacturer' and 'ProductName' fields inside Deoplyment Project properties. It needs to be the same as the folder structure your shortcut is pointing to, otherwise you'll end up with the 'The resource 'C:\Program Files (x86)[Manufacturer][ProductName]\' does not exist' error inside Event Viewer.

How do I persuade a VS2005 msi to upgrade?

I have a Windows service written in C# using VS2005.
The installation is via a wizard that calls msiexec to install the msi file also created using VS2005.
I am having trouble generating an msi file that will upgrade from one version of the service to another. The wizard program handles detection of the currently installed version, stopping the service, coming up with an appropriate command-line for msiexec and then re-starting the service.
The existing msi has a version property of 1.1.02, the new one is 1.1.03. The product and upgrade codes are identical.
Uninstalling 1.1.02 manually via add/remove programs works fine, as does installing 1.1.03 onto a "clean" system.
Upgrading 1.1.02 to 1.1.03 goes through the motions but the end result is 1.1.02 installed.
The command line that the wizard uses for upgrading is:
msiexec /qb /i "MyProduct.msi" REINSTALL="ALL" REINSTALLMODE="vos"
Where am I going wrong? I'm assuming I must have missed something fairly fundamental...
The fall-back position is to inform customers that they need to manually uninstall 1.1.02 before running the wizard to install 1.1.03 but I'd rather not have to do that.
Edited to add:
Changing the product code (as VS2005 also prompts you to) actually removes the ability to upgrade at all, as it the installer won't let you do a reinstall if that product code hasn't previously been installed.
All it will then let you do is install (and then you get the usual "service already exists" -type message).
There are several things that need to be done to get "upgrades" to work with MSI's if you want to automatically remove the previous version.
First some background information about the mysterious "codes". There are 3 codes (GUID's) associated with an MSI:
Package Code - This identifies a particular version of the MSI installer and should never be reused across builds. It must always be updated.
Product Code - This identifier is used to ID a particular version of the application. It is up to the installer author to decide when to assign a new product code.
Upgrade Code - This identifies the application and should not change through it's lifetime
The Upgrade Code should never change. For you upgrade scenerio, the Product Code must be changed for each version. Additionally, as you mentioned, you must bump the version number. The Product Code and Upgrade Code can be found by selecting your setup project and going to the Properties Window. The Package Code is hidden in Studio and will always be updated.
The item you are probably missing, is that you also need to set the RemovePreviousVersions setting in the Properties Window to true.
One more thing in addition to mohlsen's answer (For Visual Studio 2008):
In order for your Primary Output (your EXE!) to upgrade properly, you must increment the FILE VERSION
This setting can be found in the Project Properties: Application Tab -> Assembly Information
An easier way to manage this is to REMOVE the AssemblyFileVersion from all assemblies, including the main executable and all the managed DLLs.
In each of your AssemblyInfo.cs files, I recommend doing something like this if you don't care about the version numbers, but want to have some traceability.
[assembly: AssemblyVersion("1.1.*")]
// don't need this [assembly: AssemblyFileVersion("1.0.0.0")]
Everything still compiles fine, and if you don't have the AssemblyFileVersion defined, then the installer assumes that everything is different every time (which is probably fine if you are installing all of the DLLs next to the main EXE).
I spent a long time figuring this out, especially if I don't want to have to increment anything manually!

Categories

Resources