C# Service - auf PowerBroadcast reagieren

Gast #3823174
Lesenswert?

Hallo,

ich versuche gerade mit Visual Studio 2012 in C# (.Net 4.0) einen Dienst 
zu erstellen, der auf PowerBroadcasts reagiert...
1
        private void InitializeComponent()
2
        {
3
            this.CanHandlePowerEvent = true;
4
            this.ServiceName = "WinService";
5
        }
1
        protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
2
        {
3
            FileStream fs = new FileStream(folderPath + "\\logDatei.txt", FileMode.OpenOrCreate, FileAccess.Write);
4
            StreamWriter m_streamWriter = new StreamWriter(fs);
5
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
6
            m_streamWriter.WriteLine(" WindowsService: PowerEvent erkannt - " +
7
              DateTime.Now.ToShortDateString() + " " +
8
              DateTime.Now.ToShortTimeString() + "\n");
9
            m_streamWriter.Flush();
10
            m_streamWriter.Close();
11
            return base.OnPowerEvent(powerStatus);
12
        }

Der Dienst an sich scheint laut Dienste-Panel soweit zu laufen und in 
der LogDatei wird auch das Starten bzw. Beenden des Dienstes 
protokolliert(in den Methoden OnStart und OnStop wird auf die gleiche 
Weise eine Meldung in die logDatei.txt geschrieben. Schicke ich den PC 
jedoch in den StandBy und wecke ihn wieder auf, wird nichts in die 
Logdatei eingetgragen. Weiß jemand, wo der Fehler liegt?

Grüße,
Paul
Gast #3823385
Lesenswert?

Hallo tk,

ich dachte eigentlich, dass es bei Diensten reicht, wenn ich die 
CanHandlePowerEvents-Eigenschaft auf TRUE setze und dann die zur 
Eigenschaft gehörende ServiceBase-Methode überschreibe. Wobei ich mir 
nicht sicher bin, ob ich das richtig gemacht habe...

Hier ist nochmal der aktuelle Code:
1
namespace WinServiceProject
2
{
3
    using System;
4
    using System.IO;
5
    using System.ServiceProcess;
6
    class WinService : System.ServiceProcess.ServiceBase
7
    {
8
        private string folderPath = @"c:\logs";
9
        static void Main()
10
        {
11
            System.ServiceProcess.ServiceBase[] ServicesToRun;
12
            ServicesToRun =
13
            new System.ServiceProcess.ServiceBase[] { new WinService() };
14
            System.ServiceProcess.ServiceBase.Run(ServicesToRun);
15
        }
16
        private void InitializeComponent()
17
        {
18
            this.ServiceName = "WinService";
19
            this.CanHandlePowerEvent = true;
20
        }
21
        protected override void OnStart(string[] args)
22
        {
23
            WriteLog("Gestartet");
24
        }
25
        protected override void OnStop()
26
        {
27
            WriteLog("Beendet");
28
        }
29
        protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
30
        {
31
            WriteLog(powerStatus.ToString());
32
            return base.OnPowerEvent(powerStatus);
33
        }
34
        private void WriteLog(string text)
35
        {
36
            if (!System.IO.Directory.Exists(folderPath))
37
                System.IO.Directory.CreateDirectory(folderPath);
38
            FileStream fs = new FileStream(folderPath + "\\logDatei.txt", FileMode.OpenOrCreate, FileAccess.Write);
39
            StreamWriter m_streamWriter = new StreamWriter(fs);
40
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
41
            m_streamWriter.WriteLine(text + " - " +
42
                DateTime.Now.ToShortDateString() + " " +
43
                DateTime.Now.ToLongTimeString() + "\n");
44
            m_streamWriter.Flush();
45
            m_streamWriter.Close();
46
        }   
47
    
48
    }
49
}

Falls da doch noch mehr nötig ist wäre ich für einen Tipp dankbar.

Viele Grüße,
Paul
#3825011
Lesenswert?

Ich hatte das damals mit WM_POWERBROADCAST nachrichten gemacht, da meine 
Applikation in der tray lief und der User für meinen Usecase angemeldet 
war.
Ich nehme mal an, dass Dienste keine WMs erhalten?

Habe auf Codeproject ein Beispiel (1) gefunden, da macht es einer 
genauso wie du - scheint aus meiner Sicht auch plausibel. Welches 
Windows ist es denn eigentlich?

Grüße,
tk

(1) 
http://www.codeproject.com/Articles/14353/Creating-a-Basic-Windows-Service-in-C
Gast #3825597
Lesenswert?

Hallo tk,

vielen Dank für Deine Mühe. Dienste erhalten meines Wissens nach die 
Nachrichten normalerweise über eine alternative MessagePump(zumindest 
wenn man kein Fenster erzeugt). Ich habe inzwischen von jemand anderem 
den Tipp bekommen, doch einfach mal InitializeComponent() aufzurufen. 
Und schon funktionierts...

Viele Grüße,
Paul
Gast #3825789
Lesenswert?

Paul schrieb:
> wenn man kein Fenster erzeugt). Ich habe inzwischen von jemand anderem
> den Tipp bekommen, doch einfach mal InitializeComponent() aufzurufen.
> Und schon funktionierts...

Rätsel gelöst ... Wenn du die Projektdateien von VS generieren lässt, 
steht ungefähr das hier drin:

public Service1()
{
  InitializeComponent();
}

Die Grundeinstellungen kannst du dann über die Eigenschaften vornehmen, 
ohne alles in deine eigene (Teil-) Klasse schreiben zu müssen.

// Service1.Designer.cs
private void InitializeComponent()
{
  //
  // Service1
  //
  this.CanHandlePowerEvent = true;
  this.CanHandleSessionChangeEvent = true;
  this.ServiceName = "Bla";
}

Ich muss aber gestehen, dass mir nicht gleich aufgefallen ist, dass in 
deinem Code statt

public partial class Service1 : ServiceBase

das hier

class WinService : System.ServiceProcess.ServiceBase

steht. Dann musst du die Initialisierung natürlich komplett "von Hand" 
durchführen.
#3826300
Lesenswert?

Was übrigens ein Aspekt ist, den ich bei C# mehr als Fluch denn als 
Segen betrachte: Die n:m Beziehung von Klassen und Dateien. Von 
Namespaces und Verzeichnissen ganz zu Schweigen.
Da Lobe ich mir Java in der Hinsicht...

tk

PS: ja ich weiss - "schreib mal nen Windows Dienst mit Java..." ;)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren