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 タイプ、Int32 eventID、Int16 カテゴリ、Byte[ ] rawData) at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type) at WeblogicConsumerService.WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType) in C:\Program Files (x86)\CSI\WeblogicConsumerService\WeblogicConsumer. cs: C の WeblogicConsumerService.WeblogicConsumer.OnStart(String[] args) の 136 行目:

これは 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 プロパティと自動的に一致します。 (String sourceName, String currentMachineName) at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) at System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type) at WeblogicConsumerService C の .WeblogicConsumer.winEventlogMe(String logTxt, String logSrc, Char entryType):

ここに OnStop() メソッドがあります

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

これらのイベント ログは、私をかなり混乱させ始めています。他のサービスにログインするのと同じ方法を実行しましたが、そのような問題に遭遇したことはありません. このサービスでこれらのエラーが発生する可能性がありますが、私が行った他のすべてのエラーと大差ありません:(

4

2 に答える 2

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から(私の強調):

イベントログに書き込む場合は、イベントソースを指定または作成する必要があります。新しいイベントソースを作成するには、コンピューターの管理者権限が必要です。ソースは、アプリケーションを有効なエントリのソースとしてイベントログに登録します。ソースを使用して、一度に1つのログにのみ書き込むことができます。ソースは任意のランダムな文字列にすることができますが、名前はコンピューター上の他のソースとは異なる必要があります。ソースは、アプリケーションの名前または別の識別文字列であるのが一般的です。重複したソース値を作成しようとすると、例外がスローされます。ただし、単一のイベントログを複数のソースに関連付けることができます。

私が提案するのはこれです:

ソースとして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;
}

コメントのポイントrelatencyに注意してください。ログは必ずしもすぐに作成されるとは限らないため、これを念頭に置いてコーディングすることをお勧めします。EventLogInstallerを使用してログを作成することもできます。インストーラーを使用してサービスをデプロイする場合は、これがより簡単なオプションになる可能性があります。

于 2012-11-23T01:16:32.620 に答える
0

on start メソッドを過負荷にしないことが重要です。サービス開始の失敗を防ぐために、通常、onstart メソッドはメイン コードを別のスレッドとして起動します。

于 2012-11-23T03:02:38.447 に答える