Is it possible/recommended to use the InstallService element to install a Windows service written in managed code (C#)? (I tried it and it does install the service, but the service won't start)
Or does this require a custom action which invokes Installutil?
Or is there another way to do this?
I'm in a study of wix myself right now and has just succeeded to install/uninstall a managed service with just a standard ServiceInstall/ServiceControl way (and why not if we can just use sc for it).
From what I read and agree with, using a custom task with installutil is considered a bad practice:
I used to install perf counters in my .net installer, but now I'll just go the wix way for it.
By the way I had to add a ServiceControl element so service was started after the install (Start attribute) and more importantly for me, completely uninstalled during uninstall (Remove attribute).
<ServiceControl Id='ControlStansWinService' Remove='both' Name='StansWinService' Start='install' Stop='both' Wait='yes' />
I've published my findings so far here, hope you can find it useful.
You should use the WIX InstallService element as it does all the work of installing the service and starting and stopping/removing the service on install and uninstall. If you use custom action to invoke InstallUtil to install the servive, then you have to do the start and stop of the service again manually using CustomAction.
Related
I'm developing a Windows service in VS2012 and the setup/deployment part has been removed. So I'm not able to create a setup project. I would like to hear what you guys could recommend for a good easy to use the installer. I need to take some inputs, only strings, under the installation of the service. I've been looking at WiX but that seems a bit complex, and I only got 1 or 2 days to make this installer.
So what installer should I use other than Wix?
I've had really bad experiences with InstallShield LE (the one that comes with Visual Studio 2012), especially for Windows Services. The features that you need to install a service (custom actions, etc), don't come with the light version.
What I'm planning to do for the current Windows service I'm working on is to build it with Topshelf, which (amongst other things) means installing your service is as simple as running MyServiceApp.exe install. I'm sure even InstallShield will let you run your app once it's installed, and then your app/Topshelf can install the service component.
If InstallShield doesn't work for you, I've had good results before with NSIS. Simple, powerful, free, decent documentation. It looks a bit clunky.
Here is a list of setup tools which can get you started:
http://en.wikipedia.org/wiki/List_of_installation_software
If you don't have a lot of time for creating the installer, I recommend using a commercial tool like Advanced Installer or InstallShield. You need a license, but they are focused on usability (do more in less time).
You can do it with InstallShield LE... You can add custom actions "After Register Product" for install and for "After System Changes". These custom actions can run an EXE on the machine.
Make sure you run the command line tools "in system context"
After Register Product run the version of InstallUtil to your version of .NET
eg.
path=C:\Windows\Microsoft.NET\Framework\v4.0.30319
command=InstallUtil.exe "C:\Program Files (x86)\XXX\YYY\ZZZ.exe"
replacing XXX YYY and ZZZ to match your install
After System Changes to delete your service name run
e.g.
sc delete "servicename"
Note you need support for the custom actions within your own service executable (you needed this in earlier VS too).
You can find more information about SC here:
http://support.microsoft.com/kb/251192
To add an installer for a service, you just need to right-click on the designer for the service and click "Add Installer".
Here's the walkthrough:
http://msdn.microsoft.com/en-us/library/zt39148a.aspx
Using Visual Studio 2010 I have created system service installer IndexingService (property ServiceName in installer) named Indexing Service (property ProductName in setup project).
Service installs and works properly but installer won't remove system service (and therefore won't reinstall it)
What should i look for?
UPDATE: I forgot to update custom action on uninstall
Actually i forgot to configure one of the custom actions properly.
Thank you, Cosmin Pirvu!
I am using Wix3 to install WCF service to IIS.
How can I use my custom action (c#) function after installation completed? i.e. I need to open installed web.config file and replace hostname with real one.
Any ideas?
You can schedule it after InstallFinalize action in InstallExecuteSequence.
There is a sequence of Actions in Windows Installer. The WiX tutorial has a good section on events (and is a great resource anyway).
A typical example of getting something to run after InstallFinalize is to get the installed app to start.
<InstallExecuteSequence>
<Custom Action='LaunchFile' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
Why would you:
1) Need a custom action?
2) Do it after the install instead of during the install?
WiX has a built-in extension for handling what you are trying to do:
XmlFile Element (Util Extension)
It will update your XML after the file has been installed and handle rollback scenarios as well.
What you will have to write a CA for though is reading the XML value back into a property ti handle repair and upgrade situations. Read:
The WiX toolset's "Remember Property" pattern.
I have an existing (C# based) windows service that is derived from the Installer class and I currently use the MS supplied, command line InstallUtil to install it and uninstall it. This works fine and as part of my system I have attached event handlers to the AfterUninstallEventHandler and CommittedEventHandler events. In my case I simply use them to log messages to a custom event log - showing the install and uninstall dates and times and program versions.
At the moment I am experimenting with Wix v3.5 Beta 1 to package up a bunch of my stuff including this service and I am using the Wix ServiceInstall and ServiceControl to replace what I manually did with InstallUtil.
However it seems that Wix uses a totally different mechanism to InstallUtil for installing services. This is seen in the name and description of the service being controlled by Wix (as opposed to what was embedded in the service program) and that my events no longer fire (which, if a different install mechanism is being used I doubt that they would).
So is it possible for Wix to perform a service installation in the same manner as InstallUtil or am I just going to put up with the differences?
Edit
Christopher has suggested factoring out the service related definitions from my code and moving them into the Wix installer project. This makes me uneasy as now I either have to find a way to share information between two separate systems (which I have no idea how to share between the code and Wix projects) or put up with defining the information in two separate locations (very bad software practice).
From a windows installer perspective, InstallUtil is an evil antipattern because it injects fragile out of process code into a declarative programming model. The Windows Installer has long had the ServiceInstall and ServiceControl tables and this works really well. The same applies to Regasm and Regserver. We prefer to extract the COM data and author it into the installer and have MSI take care of applying the registry value rather then loading assemblies and calling entry points in the hope that it works. When it fails, you have no idea why and you can't roll the state of the machine back.
What kind of stuff are you doing in your events? I would either eliminate and/or refactor each of them into something MSI can do for you. If it's still not enough, write a DTF custom action and schedule it between InstallServices and StartServices.
I'm writing a new major upgrade of our product.
In my installer I start by finding configuration settings of the previous version, then I'd like to uninstall the previous version.
I have found several guides telling me how one should make a MSI suitable for such upgrades.
However, the previous was not an MSI.
It was not according to best practices.
It does, however, in registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{GUID} specify an UninstallString.
Using a RegistrySearch I can easy find the command below, which I store in UNINSTALL_CMD.
RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup
"C:\Program Files\InstallShield Installation Information\{GUID}\setup.exe"
-l0x9 -removeonly 4:
I cannot get the hang of the CustomAction needed to perform the actual uninstall.
<CustomAction Id="ca.UninstPrev" Property="UNINSTALL_CMD" ExeCommand="" />
The MSI logs says:
Info 1721. There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: ca.UninstallPrevious, location: RunDll32 C:\PROGRA~1\COMMON~1\INSTAL~1\PROFES~1\RunTime\10\01\Intel32\Ctor.dll,LaunchSetup "C:\Program Files\InstallShield Installation Information{GUID}\setup.exe" -l0x9 -removeonly, command:
Anyone seeing what I am doing wrong here?
Regards
Leif
I did application repackaging for a couple years at Continental Airlines where I did SMS pushes to an 18,000 seat forest. I frequently had a legacy application in the wild that was not installed using MSI that I needed to get redeployed using MSI and once that was done I supported major upgrades going forward.
These previously deployed apps typically had very broken and misbehaved uninstallers. Instead of calling these, I would use SMS to query the forest to get all the deployed versions. I would then deploy those old packages to a integration lab and work out what it was each installer did to the machine and write my own aggregated "forced cleanup" custom action that was capable of wiping the various versions of the application off the machine.
I executed this custom action prior CostInitialize so that when the new MSI did it's costing it wouldn't be influenced by the crap that was no longer on the machine. This worked for me because I pushed packages as System and I didn't have to worry about elevation issues. If you want to be fully UAC compliant you would want to run this custom code from a prereq package and either have your users run it manually or wire it into a bootstrapper to run prior to your MSI.
After a good nights sleep I found my error.
If you really read http://wix.sourceforge.net/manual-wix3/wix_xsd_customaction.htm the answer was there.
I was trying to make a type 50 custom action, launch an executable already installed on system.
Property specifies the full path to an executable to launch
ExeCommand specifies the command line arguments for this executable above.
And my fault was that I did place the full exe+command line in the Property field.
/L