我已经开发了一个32位服务,我正在Windows7家庭高级x64中运行它。
问题是当我启动它时,windows会给我以下消息
本地计算机上的wlconsumer服务已启动,然后已停止。一些服务停止
如果其他服务或程序不使用它们,则自动执行。
我在事件日志中找到以下消息
无法启动服务。System.ArgumentException:日志WLConsumer已注册为本地计算机上的源。
在System.Diagnostics.EventLoginInternal.CreateEventSource(EventSourceCreationData数据源数据)
在system.diagnostics.eventloginternal.verifyandcreatesource(字符串sourcename,字符串currentmachinename)
在system.diagnostics.eventloginternal.writeEntry(字符串消息,eventlogentryType类型,int32 eventID,int16 category,byte[]rawdata)
在System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType类型)
在C:\程序文件(x86)\ CSI\WebLogicConsumerService\WebLogicConsumer.cs中的WebLogicConsumerService.WebLogicConsumer.winEventLogme(字符串logtxt,字符串logsrc,char entryType)中:第136行
在C:\程序文件(x86)\ CSI\WebLogicConsumerService\WebLogicConsumerService.cs中的WebLogicConsumerService.WebLogicConsumerService.onstart(string[]args):第63行
位于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()方法有问题。
有人能帮我弄清楚是什么问题吗,因为我现在完全不知道如何解决这个问题。
提前付款:)
@我已经按照你的建议编辑了代码,服务已经成功启动。但一停下来,我就得到了以下信息:
无法停止服务。System.ArgumentException:源“wlConsumer2012”未在日志“serviceStop”中注册。(它已在日志“serivicestartup”中注册。)“源和日志属性必须匹配,或者您可以将日志设置为空字符串,它将自动与源属性匹配。
在system.diagnostics.eventloginternal.verifyandcreatesource(字符串sourcename,字符串currentmachinename)
在system.diagnostics.eventloginternal.writeEntry(字符串消息,eventlogentryType类型,int32 eventID,int16 category,byte[]rawdata)
在System.Diagnostics.EventLog.WriteEntry(字符串消息,EventLogEntryType类型)
在C:\程序文件(x86)\ CSI\WebLogicConsumerService\WebLogicConsumer.cs中的WebLogicConsumerService.WebLogicConsumer.winEventLogme(字符串logtxt,字符串logsrc,char entryType)中:第139行
在C:\程序文件(x86)\ CSI\WebLogicConsumerService\WebLogicConsumer.cs中的WebLogicConsumerService.WebLogicConsumer.onStop()上:第70行
位于system.serviceprocess.servicebase.deferredstop()
下面是onstop()方法
protected override void OnStop()
{
winEventlogMe("Successful stop", "ServiceStop", 'i');
}
这些事件日志开始让我很困惑。我用同样的方法登录其他服务,但从未遇到过这样的问题。我怎么能在这个服务中得到这些错误,但它与我所做的其他服务没有太大的不同:(
最佳答案
我想这是你的问题:
EventLog theEvent = new EventLog("WLConsumer");
从异常判断,我认为
WLConsumer
是事件源的名称。这意味着你最好这样做:EventLog theEvent = new EventLog(logSrc);
theEvent.Source = "WLConsumer";
这只是反过来使用参数。
如果我做一点反编译,有一个这样的检查:
if (!EventLogInternal.SourceExists(logName, machineName, true))
在您的例子中,我认为这个检查返回true,这意味着它试图创建一个名为
WLConsumer
的日志,但由于WLConsumer
已注册为事件源而失败。编辑:
当我过去使用事件日志时,我将所有内容都写到源和日志的相同组合中。在您的例子中,每次编写条目时,您似乎都在使用不同的源和日志组合。
来自MSDN(强调我的):
如果写入事件日志,则必须指定或创建事件源。您必须对计算机具有管理权限才能创建新的事件源。源在事件日志中将应用程序注册为有效的条目源。一次只能使用源写入一个日志。源可以是任意随机字符串,但名称必须与计算机上的其他源不同。源通常是应用程序的名称或另一个标识字符串。尝试创建重复的源值时引发异常。但是,单个事件日志可以与多个源相关联。
我的建议是:
使用
WLConsumer
(或WLConsumer2012
)作为源,并且定义自己的日志、“wlConsumerServiceEventLog”或其他内容;或
把日志留空。在这种情况下,它们进入应用程序日志。
不管怎样,标准做法似乎是在第一次运行服务之前执行类似的操作,例如在安装程序中(直接从上面的链接复制):
// 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创建日志。如果使用安装程序部署服务,这可能是更简单的选项。