尝试安装Windows服务 - 此代码有什么问题?

时间:2011-11-10 00:39:11

标签: c# windows-services installer

我在VS2010中创建一个包含多个服务的Windows服务项目。我试图在不使用复杂的安装程序的情况下一起安装它。但是,它似乎回滚而不起作用。

这是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[] 
        { 
            // scans Email table for outbound email jobs; uses multiple threads to lock and work on data in Email table
              new EmailLogScanner()

            // generates email digest of document status on secheduled basis; single thread
            , new EmailStatusDigester() 

            // keeps Fax table and third-party fax service accounts synchronized; uses a fixed nb of threads, one thread syncs one account at a time
            , new FaxSynchronizer()     
        };

        if (console)
        {

            foreach (IDebuggableService srv in ServicesToRun)
            {
                string[] strs = new string[] { String.Empty };
                srv.DebugStart(strs);
            }

            Console.WriteLine("Press any key to terminate...");
            Console.ReadKey();

            foreach (IDebuggableService srv in ServicesToRun)
            {
                srv.DebugStop();
            }

            Console.WriteLine("Service has exited.");
        }
        else
        {
            ServiceBase.Run(ServicesToRun);
        }
    }
}

这是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);
        }
    }

}

记录的输出(当我在命令窗口中运行daemon.exe -i时,作为管理员)显示下面的文本。另外,我得到“无法从命令行启动服务”对话框:

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's 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.

更新:当我在“aInstaller.Install(state)”行周围注释try ... catch块时,输出略有不同:

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.

是因为我已经设置了事件日志源吗?如果是这样,我如何跳过AssemblyInstaller中的该步骤?如果没有,哇? :)

1 个答案:

答案 0 :(得分:0)

你应该把这个

if (EventLog.SourceExists("YourEventSourceName"))
    EventLog.DeleteEventSource("YourEventSourceName");

服务安装开始时。