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

标签 c# windows-services installation

我在 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 block 时,我得到的输出略有不同:

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 中的该步骤?如果不是,什么? :)

最佳答案

你应该放这个

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

服务安装开始时。

关于c# - 尝试安装 Windows 服务 - 此代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8073699/

相关文章:

c# - 错误 1001 : The Specified Service Already Exists. 无法删除现有服务

ruby - Ruby 开发工具包的目录无效

linux - 无法在linux centos上安装asterisk-core库

installation - 安装 Windows Installer 4.5 后,面向 Windows Installer 3.1 的安装程序包失败

c# - 集合的一个字段上的模式匹配

c# - 当系统处于休眠状态时,Windows 服务中的计时器如何运行?

c# - 我必须在 Windows 服务中实现 Stop 方法吗?

c# - 将对象公开给 VBScript 时出现 MSScriptControl 'Specified cast is not valid'

c# - 如何像推特一样导入电子邮件联系人?

asp.net - Windows 服务应用程序可以与 Web 应用程序共享 bin 文件夹吗?