【问题标题】:Windows service Started and stopped automatically, exception handling issueWindows服务自动启动和停止,异常处理问题
【发布时间】:2012-11-23 00:38:38
【问题描述】:

我开发了一个 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 类型,Int32 eventID,Int16 类别,Byte[] rawData) 在 System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType 类型) 在 C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs: 136 行中的 WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType) 在 C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 63 中的 WeblogicConsumerService.WeblogicConsumer.OnStart(String[] args) 在 System.ServiceProcess.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() 方法有问题。 有人可以帮我找出问题所在,因为我现在完全不知道如何解决这个问题。

提前感谢 :)


@nick_w 我已按照您的建议编辑了我的代码,服务已成功启动。但在停止它时,我收到以下消息:

未能停止服务。 System.ArgumentException:源“WLConsumer2012”未在日志“ServiceStop”中注册。 (注册在日志'ServiceStartup'中。) " Source 和 Log 属性必须匹配,或者您可以将 Log 设置为空字符串,它会自动匹配 Source 属性。 在 System.Diagnostics.EventLogInternal.VerifyAndCreateSource(字符串 sourceName,字符串 currentMachineName) 在 System.Diagnostics.EventLogInternal.WriteEntry(字符串消息,EventLogEntryType 类型,Int32 eventID,Int16 类别,Byte[] rawData) 在 System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType 类型) 在 C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs: 139 行中的 WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType) 在 C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer.cs:line 70 中的 WeblogicConsumerService.WeblogicConsumer.OnStop() 在 System.ServiceProcess.ServiceBase.DeferredStop()

这里是 OnStop() 方法

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

这些事件日志开始让我很困惑。我做过同样的方法登录其他服务,从来没有遇到过这样的问题。我怎么能在这个服务中得到这些错误,但它与我所做的所有其他错误并没有太大区别:(

【问题讨论】:

  • 如果您仍在解决这个问题,请查看我的最新编辑。

标签: c# .net windows service


【解决方案1】:

我认为这是你的问题:

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 值会引发异常。 但是,单个事件日志可以与多个来源相关联。

我的建议是这样的:

使用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;
}

注意 cmets re 延迟中的点。日志不一定会立即创建,因此在编写代码时要牢记这一点。您也可以使用EventLogInstaller 创建日志。如果您使用安装程序来部署服务,这可能是更简单的选择。

【讨论】:

  • 注意:区分日志源时只考虑前 *** 8 *** 个字符。 MyLogSource1 没问题,MyLogSource2 创建时会报错。
【解决方案2】:

不要重载 on start 方法很重要,为了防止服务启动失败,通常 onstart 方法将主代码作为单独的线程启动

【讨论】:

  • 你是什么意思。默认情况下,新服务模板中的 onstart 会被覆盖。我从来没有尝试过改变那部分,因为我从来没有遇到任何问题。
  • 两种类型的活动会杀死一个windows服务,未处理的异常和超过服务器onstart方法的启动阈值见[链接](serverfault.com/questions/111045/…)
猜你喜欢
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 2015-04-27
  • 2011-11-14
  • 2014-07-06
相关资源
最近更新 更多