我开发了32位服务,我在Windows 7 Home Premium x64中运行它。 问题是,当我启动它时,Windows会给我以下消息
本地计算机上的WLConsumer服务已启动然后停止。一些服务停止 如果他们没有被其他服务或程序使用,则自动。
我在事件日志中找到了以下消息
无法启动服务。 System.ArgumentException:Log WLConsumer已在本地计算机上注册为源。 在System.Diagnostics.EventLogInternal.CreateEventSource(EventSourceCreationData sourceData) 在System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName,String currentMachineName) at System.Diagnostics.EventLogInternal.WriteEntry(String message,EventLogEntryType type,Int32 eventID,Int16 category,Byte [] rawData) 在System.Diagnostics.EventLog.WriteEntry(String message,EventLogEntryType type) 在C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs中的WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt,String logSrc,Char entryType):第136行 在WeblogicConsumerService.WeblogicConsumer.OnStart(String [] args)中的C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs:第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()方法显然有问题。 有人可以帮我弄清楚问题是什么,因为我现在完全不知道如何解决这个问题。
预先thanx:)
@nick_w我已根据您的建议编辑了我的代码,该服务已成功启动。但在停止它时,我得到以下消息:
无法停止服务。 System.ArgumentException:源'WLConsumer2012'未在日志'ServiceStop'中注册。 (它在日志'SeriviceStartup'中注册。)“Source和Log属性必须匹配,或者您可以将Log设置为空字符串,它将自动匹配Source属性。 在System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName,String currentMachineName) at System.Diagnostics.EventLogInternal.WriteEntry(String message,EventLogEntryType type,Int32 eventID,Int16 category,Byte [] rawData) 在System.Diagnostics.EventLog.WriteEntry(String message,EventLogEntryType type) 在WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt,String logSrc,Char entryType)中的C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs:第139行 在C:\ Program Files(x86)\ CSI \ WeblogicConsumerService \ WeblogicConsumer.cs中的WeblogicConsumerService.WeblogicConsumer.OnStop():第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
)作为您的来源,
无论如何,标准做法似乎是在第一次运行服务之前做这样的事情,例如在安装程序中(直接从上面的链接复制):
// 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创建日志。如果您使用安装程序部署服务,这可能是更容易的选择。
答案 1 :(得分:0)
关键是不要重载on start方法并且为了防止服务启动失败,通常onstart方法将主代码作为单独的线程启动