Wix: How far can I go with custom action? - c#

I want to build a Wix installer which will detect a few programs of mine and update them.
I have c# code (using another DLL) to check a few things on the system,
then I want to download a table of the most recent version of all the apps,
decide which app I need to update, and then download & update the selected ones.
So my question is, can Wix preform the following actions:
1) run another dll call using c#?
2) download a file from the web and parse it (let's say - also using c#)?
3) go to a link and download an MSI\EXE?
4) install the MSI\EXE (let's say run it on silent mode)?
5) uninstall old other apps from system?

Windows Installer has a mutex that only allows 1 execute sequence per machine and 1 UI sequence per process. One MSI cannot install another MSI due to this limitation. There are hacks around this but they don't follow good design (don't provide proper elevation support or silent install / uninstall support ).
You should use custom actions with care. A properly designed custom action should behave like the standard actions built into Windows Installer. That is support transactional installation whenever possible and be data driven via custom tables.
A better candidate for the stuff you are describing needing to be done would probably be a bootstrapper / chainer such as WiX's Burn feature.

1) - definitely yes
2)-5) you could do it but you should differ msi from "custom bootstrapper" and "custom after install configuration manager". General rule: use msi package only for resource (usually files; in more complex cases - registry, in most cases sql objects) atomic deployment; move all other functionality outside msi (means use wix ony to build msi; create custom utilities for bootstrapper and configuration tool; see wix samples how to integrate three parts together).

1) Yes but keep in mind that if you have a dependency on .NET 3.5 and you are on a box with .NET 4 your custom action will not be able to run.
Besides this your custom action dll is unpacked from the msi into the %TEMP% folder. If you have any dependency to other dlls not stored in the GAC you will fail to load. If you bring in another e.g. C++ dll you have to embed it as resource in your C# dll and unpack it as well to find it.
2) You can do whatever you have the rights for.
3) Sure
4) Only one MSI installation can run at one time. You have to spawn some child process to wait until the current installation is over.
5) Yes sure. The easiest way is to add an Upgrade table to your msi to simply uninstall any software which has this upgrade code. This is the only allowed action where two msis at the same time can be active. Look at the InstallExecute Sequence table for RemoveExistingProducts action.

Related

How to make one installer dependent upon other, while installing application in windows?

I am struggling with a issue of making one installer dependent upon other.Suppose i have a setup project Through which, i use to make MSI(or setup) of my c# application for deployment on windows machine. Now suppose i have another project whose MSI(or setup) is generated by another setup project.
Now what i want to make is that when my first setup is run than it will first check for whether second MSI(or setup) is installed or not. If its not installed on target machine then it first set up will run and install second setup, once second set up is properly installed then installer of first continues and completes the its installation.
I can't figure it out how can i check whether second setup has installed or not. i.e how to make second installer dependent upon first installer. I am using visual studio 2013 and the project which i am deploying is c# application
First time i am dealing with making setups for application deployment so may be my way of asking may not be good. Thankyou!
In general that is not possible by means of MSI only since you can't run two MSI installers at the same time. You'll need to use some external solution: a self-made script, InstallShield wrapper etc. The only thing you can do within the MSI is to check that a prerequisite application is installed and if it's not - abort the installation.
Yes, you need to use a packaging tool that either offer out of the box support or you will have to write your own code for this.
You have quite few options here:
-InstallShield
-AdvancedInstaller
-Wix
What you are trying to achieve is known as prerequisite or runtimes required by your application.
As J.Tribbiani mentioned in his answer the solution you need is to use a professional tool like Advanced Installer or the others, to configure your setup as a prerequisite. This is the standard procedure for your requirement.
Here is an example tutorial of how to do it with Advanced Installer:
prerequisite configuration
Or a video of configuring an optional prerequisite, i.e. which the users could choose to skip (let's say if they have an equivalent alternative or want to manually install the prerequisite)
Disclaimer: I work on the team building Advanced Installer

what is happening when installing a software/application in windows os?

i created an application using c# language. this application is doing a task like report generation.i am using that application exe file directly to run the application.i never installed that application in my system. without installation of that application, i can use it in my system.then why people are installing a software/application in systems.please clarify me. so that i can differentiate the MSI installation and direct use of exe file.
Install in cs jargon means guided setup, so what you do is already, basically, installing. Installing may involve much more complicated steps than simple copy/paste of bin directory or unzipping in some folder. installation process may contain the below processes:
Controlling user license
Registry key control
Database creation
Com components registration
....
and much more.
But the core concept remains the same: guided setup of all necessary components of your program to run it properly. So, if the only thing your program needs is a binaries folder, copy/paste is your install.
What you are doing is called an "xcopy" deployment. It was all the rage when .NET came out but it has serious limitations.
Windows Installer (MSI) is a windows platform service / SDK that aimed to create a declarative framework for consistent installer behavior. Simply put instead of learning how to write script to automate install/uninstall (and making a lot of mistakes along the way) you leverage MSI to tell it I have a product named X with feature Y that has these files Z in these directories along with a shortcut and some registry entries and let MSI do the rest for you.

install windows service in custom actions

I have created a c# 4.0 windows service. I have created an installer project (.msi) for it which installs the service to a particular folder.
To automate the process fully, I would like to install the service as part of the custom actions I have for my installer.
How can I code my custom actions to install or when uninstalling the msi, uninstall the windows service?
You can use the ServiceInstaller class. A quick solution would be to find installutil tool and execute it against your Service.exe, but you have to capture the output to see whether the installation succeeded or not and you don't have much control over Install, Commit, Rollback, and Uninstall phases.
Simple answer: don't. The proper way is to install it using the MSI database itself, i.e. ServiceInstall and ServiceControl tables. Every single "convenient" IDE for MSI creation and also WiX come with primitives to make use of this builtin facility.
The very reason that this is best practice, just like including the COM registration in your MSI instead of calling DllRegisterServer of the COM (DLL) to register is that your application may be defunct at the time the user attempts to remove it.
The database actions can still be executed even by a newer Windows Installer, say after an upgrade of Windows itself, while your code may refuse to run or may not run for other reasons.

Self-Extracting Zip: Specify Extraction Path With .exe File

I'm working on a deployment plan for a C# Winforms application and would like to use a self-extracting .zip file to distribute all of the required files. Here is the file structure of the SFX:
Setup.exe
app.exe
app2.exe
readme.txt
manual.pdf
After the user runs the SFX, I want Setup.exe to take control and copy app.exe, app2.exe, readme.txt, and manual.pdf to location x. The path they are copied to will depend on choices the user makes from the UI of Setup.exe, system properties, etc.
How would I go about writing Setup.exe in C#?
Personally, I had very good experiences with using NSIS as a setup tool. It's a bit more than a SFX but really good to use, rather flexible and free-of-charge.
So I recommend that you do not write your own SFX in C# (aka "re-inventing the wheel") but rather use something existing that is real-world-proofen.
There are, of course, a lot of other installers available.
I agree, don't waste your time writing an installer when there are already ones available. If you did chose to write one on your own for whatever reason, I would encourage you to stay away from any languages that require dependencies (e.g. C# requires the .Net Runtime). I would suggest using C or C++ and turning on static linking using the /MT flag so that your installer is dependent on as little as possible.
Some of the installation software I've used (in order of preference):
Nullsoft Scriptable Install System (NSIS) - This is a free scripted installer which has a large user base including Firefox, DOSBox, 7-Zip, Winamp, and even Dropbox.
Inno Setup - This one is free, and the project files are setup more like an INI file. Overall, very easy to work with, but not as feature rich as NSIS. There is a visual editor called ISTool which makes it even easier to work with.
Visual Studio Installer / Microsoft Windows Installer - It comes with Visual Studio, and it works well enough. It creates a MSI setup package.
See the list of installation software article on Wikipedia for other options.

.NET Compact Framework - CAB auto update on Windows Mobile 6.5

I'm developing an auto update feature for my Windows Mobile 6.5 .NET CF 3.5 application.
I haev ended up with following solution.
I use SOAP WebService to check whether a new version of application is available.
If there is a newer version, I get the URL in SOAP response, download it. The new version is simply a CAB full installation file.
As soon as the version is downloaded i call wceload with /silent and /noui parameters on the downloaded CAB. I want unattended installation because users of this application are car drivers who are not so skill-full at operating mobile devices.
The process goes smoothly with one exception - the /noui or /silent options forces wceload to not display any window. My application simply dissapears and in the background the new version is installed. The problem is the drivers sometimes try to turn the application on again too soon. Another point is I'd like my application starts automatically after the update process is completed. So I created a separate exe application that simply calls wceload and if it completes installation it runs the updated version. All works with onr exception - this installer exe is part of my CAB so it is within it and when wceload installs the CAB, it shuts down the installer (because it is a part of the CAB installer). Thus, the installation process is interrupted.
My question is - is there a way to "tell CAB" to not terminate particular exe from those one that are part of this CAB?
Regards
It is not really responding to your question but you can do the following :
launch another (small) executable showing a "Update in progress" screen.
do your stuff behind the scene
[end of setup] => it starts your updated app
[Wait a little bit] => it closes itself and the updated app is ready to use
CAB installation and WCELOAD are limited in many ways. You're after some sort of UI that tells the user that things are in progress and you're wanting to conditionally install certain pieces of a CAB and that simply isn't achievable with wceload out of the box. You might be able to hack some of this together with a custom setup DLL, but I think the "conditional install pieces" is going to still be the show stopper.
One alternative is to not use wceload, but instead create your own CAB extraction tool. You could then do all of your own UI and custom logic based on the file name, etc. I put together an SDK and sample installer several years ago that would allow this - admittely it's not free, but the lowest cost option is only $5 so it's pretty close.
Newer CABs actually contain an XML doc that describes the install actions (in addition to the older .000 binary file descriptor that the SDK I wrote decodes), so it's also possible that you could do all of the extraction just using that and save the $5.
Dont use a cab. Use a tar.gz package with an executable and the cab inside. Use SharpZipLib for decompression. Just run the executable to do the work. Use the \windows\wceload tool to run the cab install.

Categories