none
datei wird nicht mehr jede 2 min generiert(windows Dienst) RRS feed

  • Frage

  • Hallo,

    Ich habe ein windows Dienst. In diesen windows Dienst habe ich ein programm angehängt. dieses Programm generiert eine Textdatei. mit windows dienst sollte die Textdatei jede 2 min generieren. Der windows Dienst hat immer funcktionniert, seit gestern wird die Textdatei nur einmal beim Rechner Start erstellt.

    warum erstellt nicht den Windows dienst, die Textdatei jede 2 min?

    danke im voraus

    Lg

    Mittwoch, 19. August 2015 08:26

Antworten

  • Hallo Matsak,

    ich habe Deinen Code nur minimal geändert.

    Die zeitintensive Routine habe ich im Timer-Handler ausgelagert. Der Timer-Interval wird manuell gesteuert, damit der Timer nicht mitten in der Operation feuert. Das Ganze muss freilich noch viel bearbeitet werden um wirklich robust zu sein.

    Teste den Code (und stelle sicher, dass Du im richtigen Log schaust, d.h. unter Anwendungs- und Dienstprotokolle > NewLog).

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace InterfaceService
    {
        public partial class InterfaceDienst : ServiceBase
        {
            private int _EventId;
            private System.Timers.Timer _Timer;
            private System.Diagnostics.EventLog eventLog1;
    
            [DllImport("advapi32.dll", SetLastError = true)]
            private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
    
            //[DllImport("Interface.dll", SetLastError = true)]
            //private static extern bool SetServiceStatus1(IntPtr handle1, ref ServiceStatus serviceStatus1);
    
            public enum ServiceState
            {
                SERVICE_STOPPED = 0x00000001,
                SERVICE_START_PENDING = 0x00000002,
                SERVICE_STOP_PENDING = 0x00000003,
                SERVICE_RUNNING = 0x00000004,
                SERVICE_CONTINUE_PENDING = 0x00000005,
                SERVICE_PAUSE_PENDING = 0x00000006,
                SERVICE_PAUSED = 0x00000007,
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct ServiceStatus
            {
                public long dwServiceType;
                public ServiceState dwCurrentState;
                public long dwControlsAccepted;
                public long dwWin32ExitCode;
                public long dwServiceSpecificExitCode;
                public long dwCheckPoint;
                public long dwWaitHint;
            };
    
            public InterfaceDienst(string[] args)
            {
                InitializeComponent();
                string eventSourceName = "Source";
                string logName = "NewLog";
    
                if (args.Count() > 0)
                {
                    eventSourceName = args[0];
                }
                if (args.Count() > 1)
                {
                    logName = args[1];
                }
                eventLog1 = new System.Diagnostics.EventLog();
                if (!System.Diagnostics.EventLog.SourceExists(eventSourceName))
                {
                    System.Diagnostics.EventLog.CreateEventSource(eventSourceName, logName);
                }
                eventLog1.Source = eventSourceName;
                eventLog1.Log = logName;
            }
    
            protected override void OnStart(string[] args)
            {
                eventLog1.WriteEntry("Dienst startet...");
    
                try
                {
                    // Update the service state to Start Pending.
                    ServiceStatus serviceStatus = new ServiceStatus();
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                    serviceStatus.dwWaitHint = 100000;
    
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                    // Set up a timer to trigger every 10 seconds.
                    _Timer = new System.Timers.Timer();
                    _Timer.Interval = 10000; // 10 seconds
                    _Timer.AutoReset = false;
                    _Timer.Elapsed += this.OnTimer;
                    _Timer.Start();                
    
                    // Update the service state to Running.
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                }
                catch (Exception ex)
                {
                    eventLog1.WriteEntry("Fehler beim Starten des Dienstes: " + ex.Message);
                }
    
                eventLog1.WriteEntry("Dienst gestartet");
    
            }
    
            private void OnTimer(object sender, System.Timers.ElapsedEventArgs e)
            {
                _EventId = 0;
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, _EventId++);
    
                // Do time consuming tasks here
                //Interface.Program MyExport = new Interface.Program();
                //MyExport.Export();
    
                _Timer.Start();
            }
    
            protected override void OnStop()
            {
                eventLog1.WriteEntry("Dienst Stop.");
            }
        }
    }
    

    Marcel

    • Als Antwort markiert Matsak Donnerstag, 27. August 2015 06:34
    Dienstag, 25. August 2015 17:58
    Moderator
  • Hallo,

    Jetzt verstehe, die methode Export generiert die Dateien. Der Aufruf von MyExport.Export() muss nicht in InitializeServiceJob Methode sondern in OnTimer() Methode stattfinden.

    public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
            {
                Interface.Program MyExport = new Interface.Program();
                MyExport.Export();
                 
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
            }

    In diesem Fall kannst Du den Thread  sparren und den Timer in OnStart() initialisieren.

    Grüße




    • Bearbeitet Iso7 Mittwoch, 26. August 2015 14:47
    • Als Antwort markiert Matsak Donnerstag, 27. August 2015 06:35
    Mittwoch, 26. August 2015 14:45

Alle Antworten

  • Hi,

    das kann dir keiner beantworten, da keiner deinen Code kennt.

    Poste daher bitte die relevanten Informationen, insbesondere zu dem von dir verwendeten Timer, ggfs. auftretende Fehlermeldungen (ja, die brauchen wir, notfalls musst Du deine Anwendung erweitern, so dass die Fehler protokolliert werden).

    Ansonsten schau mal ins Windows Ereignisprotokoll, evtl. findet sich dort etwas zu dem Problem.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 19. August 2015 08:53
    Moderator
  • Hi,
    ich vermute, dass es beim ersten Start einen Fehler gibt, der nicht ausreichend behandelt wird und deshalb der Service das Programm kein weiteres Mal aufrufen kann. Da es bisher immer funktioniert hat, können beispielsweise erschöpfte Ressourcen die Ursache sein. 

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 19. August 2015 08:54
  • Hallo,

    Danke für Ihre Hilfe. Ich habe mein Timer in OnStart implementiert.

      protected override void OnStart(string[] args)
            {
                eventLog1.WriteEntry("In OnStart");
                try
                {
                    // Update the service state to Start Pending.
                    ServiceStatus serviceStatus = new ServiceStatus();
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                    serviceStatus.dwWaitHint = 100000;
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                    // Set up a timer to trigger every minute.
                    int eventId = 0;
                    System.Timers.Timer timer = new System.Timers.Timer();
                    timer.Interval = 120000; // 120 seconds (1 min = 60 000)
                    timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
                    timer.Start();
    
                   Interface.Program myexport = new Interface.Program();
                    myexport.Export();
    
                    eventLog1.WriteEntry("Interface Erstellen", EventLogEntryType.Information, eventId++);
    
                    // Update the service state to Running.
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
                }
                catch (Exception ex)
                {
    
                    EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error);
                }
               
            }
    Interface.dll ist schon in verweis. und Interface.Programm() funktionniert fehlerfrei.

    Ich kann den Dienst nicht mehr starten. ich bekomme folgende Fehler meldung

    Der Dienst"Display Name" auf "Lokaler Computer" konnte nicht gestartet werden.
    
    Fehler 1053: Der Dienst antwortete nicht rechzeitig auf Start-oder Steuerungsanforderung.

    Kann mir jemand sagen, warum der Dienst bei mir nicht starten kann?

    Danke


    • Bearbeitet Matsak Montag, 24. August 2015 13:26
    Montag, 24. August 2015 13:23
  • Hi,
    wichtig ist, was im OnTimer passiert, da es ja 1 Mal funktioniert.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks

    Montag, 24. August 2015 13:30
  • das ist die OnTimer Methode.

       public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
            {
                int eventId = 0;
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
            } 

    jetzt kann ich gar nichts mehr starten.

    danke im voraus

    Montag, 24. August 2015 13:35
  • Hi,
    nach einem Systemneustart Ist keine Start möglich?

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks

    Montag, 24. August 2015 14:02
  • hallo,

    beim Lokale Dienste Anzeigen. wenn ich mein dienst auwähle, und auf Starten drücken, fängt den Dienst zu starten an, dann bekomme ich den Fehler oben

    Montag, 24. August 2015 14:18
  • Hallo,

    es gehört zum guten Ton, die Quelle des Codes anzugeben :-)
    In Deinem Fall stammt der Code aus einem bekannten MSDN-Walkthrough.

    Ebenfalls dort findest Du dies:

    OnStart doesn’t actually do the monitoring. The OnStart method must return to the operating system after the service's operation has begun. It must not loop forever or BLOCK.

    Mit anderen Worten: Halte diesen Handler schlank. Alles was blockiert, z.B. der Aufruf von myExport.Export() gehört wahrlich nicht hierher, sondern in einem separaten Handler. Und zwar *nicht* auf dem Hauptthread, sondern in einem Hintergrundthread (BackgroundWorker).

    Marcel

    Montag, 24. August 2015 16:46
    Moderator
  • Hallo,

    wie baue ich der Aufruf von myExport.Export() in einem separaten Handler (Hintergungthread)?

    Ich habe im programm ein neues ServiceStatus1 definiert (siehe code unten)

    ich bekomme folgende Fehler in lokale Dienst beim starten

    Dienst "InterfaceService" wurde auf "Lokale Computer" gestartet und dann angehalten.
     Einige Dienste werden automatisch angehalten,wenn sie nicht von anderen Diensten oder Programmen verwendet werden.

    code

    namespace InterfaceService
    {
        public partial class NCCGInterfaceDienst : ServiceBase
        {
            private System.ComponentModel.IContainer components;
            [DllImport("advapi32.dll", SetLastError = true)]
            private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
    
            [DllImport("Interface.dll", SetLastError = true)]
            private static extern bool SetServiceStatus1(IntPtr handle1, ref ServiceStatus serviceStatus1);
            public enum ServiceState
            {
                SERVICE_STOPPED = 0x00000001,
                SERVICE_START_PENDING = 0x00000002,
                SERVICE_STOP_PENDING = 0x00000003,
                SERVICE_RUNNING = 0x00000004,
                SERVICE_CONTINUE_PENDING = 0x00000005,
                SERVICE_PAUSE_PENDING = 0x00000006,
                SERVICE_PAUSED = 0x00000007,
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct ServiceStatus
            {
                public long dwServiceType;
                public ServiceState dwCurrentState;
                public long dwControlsAccepted;
                public long dwWin32ExitCode;
                public long dwServiceSpecificExitCode;
                public long dwCheckPoint;
                public long dwWaitHint;
            };
    
            public InterfaceDienst(string[] args)
            {
                InitializeComponent();
                string eventSourceName = "Source"; 
                string logName = "NewLog";  
                if (args.Count() > 0)
                {                
                    eventSourceName = args[0];
                } 
                if (args.Count() > 1)  
                { 
                    logName = args[1];
                }          
                eventLog1 = new System.Diagnostics.EventLog();
                if (!System.Diagnostics.EventLog.SourceExists(eventSourceName)) 
                {               
                    System.Diagnostics.EventLog.CreateEventSource( eventSourceName, logName); 
                }           
                eventLog1.Source = eventSourceName;
                eventLog1.Log = logName;
            }
    
            
            public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
            {
                int eventId = 0;
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
            }
            protected override void OnStart(string[] args)
            {
                eventLog1.WriteEntry("Dienst Start");
                // Update the service state to Start Pending.
                ServiceStatus serviceStatus = new ServiceStatus();
                serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                serviceStatus.dwWaitHint = 100000;
                SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                ServiceStatus serviceStatus1 = new ServiceStatus();
                serviceStatus1.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                serviceStatus1.dwWaitHint = 100000;
                SetServiceStatus1(this.ServiceHandle, ref serviceStatus1);
    
                // Set up a timer to trigger every minute.
                System.Timers.Timer timer = new System.Timers.Timer();
                timer.Interval = 120000; // 60 seconds
                timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
                timer.Start();
    
             Interface.Program MyExport = new Interface.Program();
                MyExport.Export();
    
                // Update the service state to Running.
                serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
                SetServiceStatus(this.ServiceHandle, ref serviceStatus);
                serviceStatus1.dwCurrentState = ServiceState.SERVICE_RUNNING;
                SetServiceStatus1(this.ServiceHandle, ref serviceStatus1);
            }
    
    
            protected override void OnStop()
            {
              
                eventLog1.WriteEntry(" Dienst Stop.");
    
            }
        }
    }

    Danke im voraus

    Lg



    • Bearbeitet Matsak Dienstag, 25. August 2015 09:21
    Dienstag, 25. August 2015 09:19
  • Hallo,

    Timer als Klassen-Variable deklarieren:

    public partial class NCCGInterfaceDienst : ServiceBase
        {
          private System.Timers.Timer serviceTimer=null;

    In OnStart Methode Thread starten:

    protected override void OnStart(string[] args)
            {
                eventLog1.WriteEntry("Dienst Start");
                // Update the service state to Start Pending.
                ServiceStatus serviceStatus = new ServiceStatus();
                serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                serviceStatus.dwWaitHint = 100000;
                SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
    
                Thread initThread = new Thread(new ThreadStart(this.InitializeServiceJob));
                initThread.Start();
    
                
    
                // Update the service state to Running.
                serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
                SetServiceStatus(this.ServiceHandle, ref serviceStatus);
                
            }
    
    
    


    Thread-Methode:

    private void InitializeServiceJob() { Interface.Program MyExport = new Interface.Program(); MyExport.Export(); // Set up a timer to trigger every minute.

    if(serviceTimer==null)

    { serviceTimer = new System.Timers.Timer(); serviceTimer.Interval = 120000; // 60 seconds serviceTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer); serviceTimer.Start(); }

    else

    {

    serviceTimer.Enabled = true;

    } }

    protected override void OnStop()
            {
                serviceTimer.Enabled  = false;
              
                eventLog1.WriteEntry(" Dienst Stop.");
    
            }

    Grüße


    Dienstag, 25. August 2015 14:34
  • Hallo Matsak,

    ich habe Deinen Code nur minimal geändert.

    Die zeitintensive Routine habe ich im Timer-Handler ausgelagert. Der Timer-Interval wird manuell gesteuert, damit der Timer nicht mitten in der Operation feuert. Das Ganze muss freilich noch viel bearbeitet werden um wirklich robust zu sein.

    Teste den Code (und stelle sicher, dass Du im richtigen Log schaust, d.h. unter Anwendungs- und Dienstprotokolle > NewLog).

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace InterfaceService
    {
        public partial class InterfaceDienst : ServiceBase
        {
            private int _EventId;
            private System.Timers.Timer _Timer;
            private System.Diagnostics.EventLog eventLog1;
    
            [DllImport("advapi32.dll", SetLastError = true)]
            private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
    
            //[DllImport("Interface.dll", SetLastError = true)]
            //private static extern bool SetServiceStatus1(IntPtr handle1, ref ServiceStatus serviceStatus1);
    
            public enum ServiceState
            {
                SERVICE_STOPPED = 0x00000001,
                SERVICE_START_PENDING = 0x00000002,
                SERVICE_STOP_PENDING = 0x00000003,
                SERVICE_RUNNING = 0x00000004,
                SERVICE_CONTINUE_PENDING = 0x00000005,
                SERVICE_PAUSE_PENDING = 0x00000006,
                SERVICE_PAUSED = 0x00000007,
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct ServiceStatus
            {
                public long dwServiceType;
                public ServiceState dwCurrentState;
                public long dwControlsAccepted;
                public long dwWin32ExitCode;
                public long dwServiceSpecificExitCode;
                public long dwCheckPoint;
                public long dwWaitHint;
            };
    
            public InterfaceDienst(string[] args)
            {
                InitializeComponent();
                string eventSourceName = "Source";
                string logName = "NewLog";
    
                if (args.Count() > 0)
                {
                    eventSourceName = args[0];
                }
                if (args.Count() > 1)
                {
                    logName = args[1];
                }
                eventLog1 = new System.Diagnostics.EventLog();
                if (!System.Diagnostics.EventLog.SourceExists(eventSourceName))
                {
                    System.Diagnostics.EventLog.CreateEventSource(eventSourceName, logName);
                }
                eventLog1.Source = eventSourceName;
                eventLog1.Log = logName;
            }
    
            protected override void OnStart(string[] args)
            {
                eventLog1.WriteEntry("Dienst startet...");
    
                try
                {
                    // Update the service state to Start Pending.
                    ServiceStatus serviceStatus = new ServiceStatus();
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
                    serviceStatus.dwWaitHint = 100000;
    
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                    // Set up a timer to trigger every 10 seconds.
                    _Timer = new System.Timers.Timer();
                    _Timer.Interval = 10000; // 10 seconds
                    _Timer.AutoReset = false;
                    _Timer.Elapsed += this.OnTimer;
                    _Timer.Start();                
    
                    // Update the service state to Running.
                    serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
                    SetServiceStatus(this.ServiceHandle, ref serviceStatus);
    
                }
                catch (Exception ex)
                {
                    eventLog1.WriteEntry("Fehler beim Starten des Dienstes: " + ex.Message);
                }
    
                eventLog1.WriteEntry("Dienst gestartet");
    
            }
    
            private void OnTimer(object sender, System.Timers.ElapsedEventArgs e)
            {
                _EventId = 0;
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, _EventId++);
    
                // Do time consuming tasks here
                //Interface.Program MyExport = new Interface.Program();
                //MyExport.Export();
    
                _Timer.Start();
            }
    
            protected override void OnStop()
            {
                eventLog1.WriteEntry("Dienst Stop.");
            }
        }
    }
    

    Marcel

    • Als Antwort markiert Matsak Donnerstag, 27. August 2015 06:34
    Dienstag, 25. August 2015 17:58
    Moderator
  • Hallo,

    Danke für euere Hilfe.

    Der Vorschlag von Marcel funktioniert. der Dienst startet und generiert meine Texdatei von MyExport.Export(); jede 2 min, aber wenn ich folgende code

    Interface.Program MyExport = new Interface.Program();
      MyExport.Export();

    in methode OnTimer() schreibe.

    Der Vorschlag von Iso7 funktioniert nur bei erste Start von dem Dienst. Danach wird die Textdatei von MyExport.Export() nicht mehr generiert. Dies sollte jede 2 min generieren.

    @Iso7 ich finde deinen Vorschlag besser, weiss du warum dem Dienst meine Methode MyExport.Export(); jede 2 min nicht ausführt? vielleicht liegt das an die schleife

      if(serviceTimer==null)

    Danke

    Lg



    • Bearbeitet Matsak Mittwoch, 26. August 2015 14:01
    Mittwoch, 26. August 2015 13:59
  • Hallo,

    Jetzt verstehe, die methode Export generiert die Dateien. Der Aufruf von MyExport.Export() muss nicht in InitializeServiceJob Methode sondern in OnTimer() Methode stattfinden.

    public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
            {
                Interface.Program MyExport = new Interface.Program();
                MyExport.Export();
                 
                // TODO: Insert monitoring activities here.
                eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
            }

    In diesem Fall kannst Du den Thread  sparren und den Timer in OnStart() initialisieren.

    Grüße




    • Bearbeitet Iso7 Mittwoch, 26. August 2015 14:47
    • Als Antwort markiert Matsak Donnerstag, 27. August 2015 06:35
    Mittwoch, 26. August 2015 14:45
  • Hallo,

    Ok. Genau wie den Vorschlag von Marcel. Jetzt klappt alles super.

    Vielen Dank

    schöne Grüsse

    Donnerstag, 27. August 2015 06:34