2012-11-23 124 views
4

我开发了一个32位服务,我在Windows 7 Home Premium x64上运行它。 问题是当我启动它,窗口给我以下消息Windows服务自动启动和停止,异常处理问题

本地计算机上的WLConsumer服务启动,然后停止。如果某些服务未被其他服务或程序使用,则会自动停止 。

我发现在事件以下信息登录

服务无法启动。 System.ArgumentException:日志WLConsumer已被注册为本地计算机上的源。 在System.Diagnostics.EventLogInternal.CreateEventSource(EventSourceCreationData sourceData) 在System.Diagnostics.EventLogInternal.VerifyAndCreateSource(字符串SOURCENAME,字符串currentMachineName) 在System.Diagnostics.EventLogInternal.WriteEntry(字符串消息,EventLogEntryType类型,事件ID的Int32,Int16类型类别(x86)\ CSI中的WeblogicConsumerService.WeblogicConsumer.winEventlogMe(字符串logTxt,字符串logSrc,Char entryType) 处的System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType类型) \ WeblogicConsumerService \ WeblogicConsumer.cs:line 136 at C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs中的WeblogicConsumerService.WeblogicConsumer.OnStart(String [] args):line 63 at System.Serv iceProcess.ServiceBase.ServiceQueuedMainCallback(对象状态)

这是我在的OnStart()方法

protected override void OnStart(string[] args) 
    { 
     #region WEBLOGIC CREDENTIALS 
     try 
     { 
      //Weblogic URL 
      this.url = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("URL").ToString(); 

      //Queue name 
      this.qName = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("Queue").ToString(); 

      //Weblogic login name 
      this.user = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("User").ToString(); 

      //Weblogic password 
      this.pwd = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("Pwd").ToString(); 

      //Weblogic Connection Factory 
      this.cfName = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("ConnectionFactory").ToString(); 

      //root folder 
      this.rFolder = Registry.LocalMachine.OpenSubKey(@"Software\CSI_WL").GetValue("root").ToString(); 
     } 
     catch (Exception e) 
     { 
      winEventlogMe(e.Message, "WLRegistryKeys", 'e'); 
     } 
     #endregion 

     winEventlogMe("Successful start", "SeriviceStartup", 'i'); 
     synchro.Enabled = true; 
    } 

代码块winEventLogMe是我打电话给记录的方法。

 public static void winEventlogMe(string logTxt, string logSrc, char entryType) 
    { 
     #region Log 
     //Log to event log 

     EventLog theEvent = new EventLog("WLConsumer"); 
     theEvent.Source = logSrc; 
     if (entryType == 'e') 
      theEvent.WriteEntry(logTxt, EventLogEntryType.Error); 
     else if (entryType == 'i') 
      theEvent.WriteEntry(logTxt, EventLogEntryType.Information); 
     else if (entryType == 'w') 
      theEvent.WriteEntry(logTxt, EventLogEntryType.Warning); 
     else 
      theEvent.WriteEntry(logTxt, EventLogEntryType.Error);*/ 
     #endregion 
    } 

当我在OnStart()方法中注释掉对winEventLogMe()方法的调用时,服务启动时不会出错。所以显然winEventLogMe()方法有些问题。 有人可以帮我找出最新的问题,因为我现在对如何解决这个问题完全无能为力。

thanx提前:)


@nick_w我已经编辑我的代码,如你所说,该服务成功地启动。但在停止它时,我收到以下消息:

无法停止服务。 System.ArgumentException:源'WLConsumer2012'未在日志'ServiceStop'中注册。 (它在“SeriviceStartup”日志中注册。)“Source和Log属性必须匹配,或者您可以将Log设置为空字符串,并且它将自动匹配到Source属性 at System.Diagnostics.EventLogInternal。在System.Diagnostics.EventLogInternal.WriteEntry(字符串消息,EventLogEntryType类型,Int32 eventID,Int16类别,字节[] rawData) 在System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType类型)验证字符串(字符串sourceName,字符串currentMachineName) )在C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer中的WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt,String logSrc,Char entryType)处的 。CS:线139 在WeblogicConsumerService.WeblogicConsumer.OnStop()在C:\程序文件(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs:线70 在System.ServiceProcess.ServiceBase.DeferredStop()

这里是OnStop()方法

 protected override void OnStop() 
    { 
     winEventlogMe("Successful stop", "ServiceStop", 'i'); 
    } 

这些事件日志开始混淆了我很多。我已经完成了登录其他服务的相同方法,并且从未遇到过这样的问题。我怎样才能在这个服务中收到这些错误但其没有太大的所有其他我曾经做过:(不同

+0

如果你仍然在这个问题上的工作,看看在我最近的编辑。 –

回答

4

我觉得这是你的问题:

EventLog theEvent = new EventLog("WLConsumer"); 

由异常判断,我想。这是WLConsumer事件源的名义这意味着,你可能会与此更好。

EventLog theEvent = new EventLog(logSrc); 
theEvent.Source = "WLConsumer"; 

这仅仅是使用参数的其他方式

如果我做一个小小的反编译,有这样一个检查:

if (!EventLogInternal.SourceExists(logName, machineName, true)) 

在你的情况,我觉得这个检查返回true,这意味着它正试图创建一个名为WLConsumer日志,但失败,因为WLConsumer已被注册为事件源。

编辑:

当我使用的事件日志,在过去,我写的一切源和日志的相同组合。在你的情况下,你每次写入条目时似乎都使用不同的源和日志组合。

MSDN(重点煤矿):

如果你写一个事件日志,必须指定或创建一个事件源。您必须在计算机上拥有管理权限才能创建新的事件源。 Source将您的应用程序与事件日志一起注册为有效的条目来源。 您一次只能使用Source来写入一个日志。 Source可以是任何随机字符串,但名称必须与计算机上的其他来源不同。 来源通常是应用程序的名称或其他标识字符串。尝试创建重复的Source值会引发异常。 但是,单个事件日志可以与多个来源相关联。

我的建议是这样的:

使用WLConsumer(或WLConsumer2012)作为源,并且或者

  1. 定义自己的日志,“WLConsumerServiceEventLog`什么的;或
  2. 将日志留空。他们进入这种情况下的应用程序日志。

无论如何,标准的做法似乎是做这样的事情上运行您的服务是第一次,如在安装前(从上面的链接直接复制):

// Create the source, if it does not already exist. 
if(!EventLog.SourceExists("MySource")) 
{ 
    //An event log source should not be created and immediately used. 
    //There is a latency time to enable the source, it should be created 
    //prior to executing the application that uses the source. 
    //Execute this sample a second time to use the new source. 
    EventLog.CreateEventSource("MySource", "MyNewLog"); 
    Console.WriteLine("CreatedEventSource"); 
    Console.WriteLine("Exiting, execute the application a second time to use the source."); 
    // The source is created. Exit the application to allow it to be registered. 
    return; 
} 

注意指出评论延迟。日志不一定是立即创建的,因此考虑到这一点是值得的。您也可以使用EventLogInstaller来创建日志。如果您使用安装程序来部署您的服务,这可能更容易。

+0

注意:它只是第一个*** 8 ***字符时被考虑在不同的日志源。 MyLogSource1没问题,MyLogSource2在创建时会出错。 – OzBob

0

这是至关重要的,不要超负荷的启动方法,为了防止服务启动失败,通常OnStart方法启动主代码作为一个单独的线程

+0

你是什么意思。默认情况下,onstart在新的服务模板中被覆盖。我从来没有试图改变那部分,因为我从未遇到过任何问题。 – TnashC

+0

两种类型的活动将杀死Windows服务,未处理的异常并超过服务器onstart方法的启动阈值请参见[link](http://serverfault.com/questions/111045/how-do-we-avoid-the- 30秒的时间限制上,启动窗口服务) –