I am creating a Windows service project in VS2010 that contains several services. I tried to drop the way to install it without a complicated installer. But the rollback does not seem to work either.
Here is Program.cs:
static class Program { static void Main(string[] args) { bool install = false, uninstall = false, console = false; WindowsServiceInstaller inst = new WindowsServiceInstaller(); if (args.Length > 0) { foreach (string arg in args) { switch (arg) { case "-i": case "-install": install = true; break; case "-u": case "-uninstall": uninstall = true; break; case "-c": case "-console": console = true; break; default: Console.Error.WriteLine("Argument not expected: " + arg); break; } } } if (uninstall) { inst.InstallServices(false, args); } if (install) { inst.InstallServices(true, args); } ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] {
Here is WindowsServiceInstaller.cs:
[RunInstaller(true)] public class WindowsServiceInstaller : Installer { public WindowsServiceInstaller() { ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); serviceProcessInstaller.Account = ServiceAccount.NetworkService; serviceProcessInstaller.Username = null; serviceProcessInstaller.Password = null; Installers.Add(serviceProcessInstaller); ServiceInstaller emailLogScannerInstaller = new ServiceInstaller(); emailLogScannerInstaller.DisplayName = "Email Scanner"; emailLogScannerInstaller.StartType = ServiceStartMode.Automatic; emailLogScannerInstaller.ServiceName = "EmailLogScanner"; // must match the ServiceBase ServiceName property emailLogScannerInstaller.Description = "Scan for and sends out pending emails in stack."; Installers.Add(emailLogScannerInstaller); ServiceInstaller emailStatusDigesterInstaller = new ServiceInstaller(); emailStatusDigesterInstaller.DisplayName = "Status Digester"; emailStatusDigesterInstaller.StartType = ServiceStartMode.Automatic; emailStatusDigesterInstaller.ServiceName = "EmailDigester"; emailStatusDigesterInstaller.Description = "Prepares document status email digests."; Installers.Add(emailStatusDigesterInstaller); ServiceInstaller faxSynchronizerInstaller = new ServiceInstaller(); faxSynchronizerInstaller.DisplayName = "Fax Synchronizer"; faxSynchronizerInstaller.StartType = ServiceStartMode.Automatic; faxSynchronizerInstaller.ServiceName = "FaxSynchronizer"; faxSynchronizerInstaller.Description = "Synchronizes database with external fax service(s)."; Installers.Add(faxSynchronizerInstaller); } public void InstallServices(bool doInstall, string[] args) { try { using (AssemblyInstaller aInstaller = new AssemblyInstaller(typeof(Program).Assembly, args)) { IDictionary state = new Hashtable(); aInstaller.UseNewContext = true; try { if (doInstall) { aInstaller.Install(state); aInstaller.Commit(state); } else { aInstaller.Uninstall(state); } } catch { try { aInstaller.Rollback(state); } catch { } throw; } } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } } }
The recorded output (when I run daemon.exe -i in a command window as admin), the text below is displayed. In addition, I get the "do not start the service from the command line" dialog:
Installing assembly 'C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe'. Affected parameters are: i = assemblypath = C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe logfile = C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.InstallLog Installing service EmailLogScanner... Service EmailLogScanner has been successfully installed. Creating EventLog source EmailLogScanner in log Application... See the contents of the log file for the C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe assembly progress. The file is located at C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.InstallLog. Rolling back assembly 'C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe'. Affected parameters are: logtoconsole = i = assemblypath = C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe logfile = C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.InstallLog Restoring event log to previous state for source EmailLogScanner. Service EmailLogScanner is being removed from the system... Service EmailLogScanner was successfully removed from the system.
UPDATE: when I comment on the try ... catch block on the line 'aInstaller.Install (state), I get a slightly different output:
Installing assembly 'C:\Users\xxx\Documents\~Business\Projects\Daemon\bin\Release\Daemon.exe'. Affected parameters are: i = assemblypath = C:\Users\xxx\Documents\~Business\Projects\Da emon\bin\Release\Daemon.exe logfile = C:\Users\xxx\Documents\~Business\Projects\Daemon\ bin\Release\Daemon.InstallLog Installing service EmailLogScanner... Creating EventLog source EmailLogScanner in log Application... Source EmailLogScanner already exists on the local computer.
Is it because I already have event log sources? If so, how to skip this step in AssemblyInstaller? If not, then?:)
source share