2011-11-10 37 views
4

我在VS2010中创建了一个包含多个服务的Windows服务项目。我试图一起挑选一种方法来安装它,而不需要复杂的安装程序。但是,它似乎回滚并且不起作用。尝试安装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(状态)”行了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中的这一步?如果不是,那么? :)

+0

而这个文件位于C:\ Users \ xxx \ Documents \〜Business \ Projects \ Daemon \ bin \ Release \ Daemon.InstallLog'说的是什么? –

+0

实际上,上面的最后一块是记录到InstallLog文件的内容。 – alphadogg

+1

哦,那么是不是这个问题? “源EmailLogScanner已经存在于本地计算机上。”?看起来你可能会在每次安装时创建事件源,但推测卸载并不会删除事件源。所以在以后的时间里,由于它已经存在,所以没有创建它。 –

回答

0

你应该把这个

if (EventLog.SourceExists("YourEventSourceName")) 
    EventLog.DeleteEventSource("YourEventSourceName"); 
服务安装开始时

+0

其实,我的问题是这个的一个变种。在大会上,我有三种不同的服务。在每个服务中,我有在ServiceBase构造函数中创建EventSource的代码。看起来像ServiceInstaller在它试图创建一个EventSource之前没有检查,因此也是冲突。我将有问题的代码移到了另一种方法中,以便在服务通过控制台运行时创建源代码。 – alphadogg

+0

自实际回答以来,我给了你点数。 ;) – alphadogg

相关问题