none
Fragen zu Windows Dienst Programmierung RRS feed

  • Frage

  • Hallo zusammen,
    ich habe eine Frage zu Windows Dienst Programmierung. Bei meinem Dienst habe ich ein Variablen Zugriffsproblem, aber ist auch mein erster Dienst ;-) kann sein das ich hier irgendwas wichtiges zum Thema Dienste übersehen habe.

    In der mainService wird eine globale Variable mit True eingelesen. In der OnStart() Methode wird eine Einlesemethode aufgerufen, die aus der Config.ini den Wert in die Variable schreibt. Sie ist auch innerhalb der
    mainService True, dass kann ich im Eventlog sehen, wenn ich sie mir durch andere Methode ausgegeben lasse.

    Aber wenn ich nun in einer meiner Unterklassen, die mit inherits von mainService erben, auf diese Variable zugreife ist sie False. Aktuell sehe ich leider nicht das Problem, Brett vorm Kopp, Wald vor luter Bäumen.

    Hat einer eine Idee womit das zutun hat? Zugriffsmodifizierer sind es nicht die hab ich getestet und ja ich weiß soll man nicht
    machen globale Variablen ;-) aber jetzt am Anfang zum Test ist das schon ok, später wird das umgebaut. Aber da sind einige
    Parameter die programmweit zur Verfügung stehen müssen.

    Schon mal Danke für eure Hilfe!


    VG Daniel

    Donnerstag, 1. November 2018 10:17

Alle Antworten

  • Hallo Daniel,

    zum einen: Welche Programmiersprache verwendest Du? C# oder VB.NET? (Oder was ganz anderes?)

    Zum anderen: Inherits hat nichts mit ggfs. vorhandenen Variablenwerten zu tun, wenn Du eigene Instanzen dieser Klassen erzeugst. Jede Instanz hat ihren eigenen Lebensraum und damit auch eigene Werte.

    Wenn Du globale Werte benötigst, kannst Du zum einen eine statische Eigenschaft/Klasse/... erstellen, zum anderen kannst Du die Werte/Objekte aber auch an die entsprechenden Instanzen übergeben.

    Damit wir dir da aber weiterhelfen können, brauchen wir mehr Angaben. Daher nochmal die Frage nach der verwendeten Programmiersprache und nach deinem aktuellen Code. Poste den mal bitte auszugsweise (die Teile, die für die Fragestellung relevant sind, also den Teil, in dem Du die Dienstinstanz erstellst, den Teil, in dem Du die weiteren Instanzen der abgeleiteten Klassen erstellst, ...)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Donnerstag, 1. November 2018 11:27
    Moderator
  • Hallo Stefan,
    den Dienst schreibe ich in Visual Basic mit Visual Studio 2013 professional inkl. Update 5.

    Hier einmal auszugsweise eine Variable und das Vorgehn...

    in der mainService Klasse habe ich einige globale Variable, eine davon ist

    Public bExportOrder As Boolean

    dann habe ich die Unterklassen deklariert

    Public mail As clsMail Public db As clsDB Public export As clsExport
    Public signature As clsSignature

    die OnStart() Methode sieht wie folgt aus.

        Protected Overrides Sub OnStart(ByVal args() As String)
    
            '**************************************************
            'Dienst Statusänderung ausstehend
            Dim handle As IntPtr = Me.ServiceHandle
            _serviceStatus.currentState = Fix(State.SERVICE_START_PENDING)
            _serviceStatus.checkPoint = 1
            _serviceStatus.waitHint = 5000
            SetServiceStatus(handle, _serviceStatus)
            '**************************************************
    
            signature = New clsSignature
            mail = New clsMail
            db = New clsDB
            export = New clsExport
    
            '**************************************************
            'System.Diagnostics.Debugger.Launch()
            'System.Diagnostics.Debugger.Break()
            '**************************************************
    
            'Logging
            mainEventLog.WriteEntry(sAppname & " Service wird gestartet.", EventLogEntryType.Information, 10)
    
            INIOperation()  'Konfigurationswerte aus der Config.ini einlesen
    
            iQueryAndSendCycle = (iQueryAndSendCycle * 60 * 1000)  'umrechnen von Minuten in Millisekunden 
            signature.generatedSignature() 'eMail Signatur laden, generieren...
    
            'Timer setzen
            mainTimer = New System.Timers.Timer(iQueryAndSendCycle)     'erzeuge eine neue Timer Instanz unter Verwendung von iQueryAndSendCycle 
            mainTimer.Enabled = True                                    'enabled = true, damit auf das Elapsed Ereignis reagiert werden kann
            AddHandler mainTimer.Elapsed, AddressOf mainTimer_Elapsed   'Handler Verweis für Zugriff auf das mainTimer.Elapsed Ereignis mit Verweis auf die Methode mainTimer_Elapsed  
            mainTimer.Start()                                           'MainTimer einschalten
            mainEventLog.WriteEntry(sAppname & " Service | MainTimer wurde erfolgreich initialisiert und läuft mit " & mainTimer.Interval & " Millisek.", EventLogEntryType.Information, 10)
            mainEventLog.WriteEntry(sAppname & " Service, OnStart Wert der Variable bExportOrder = " & bExportOrder, EventLogEntryType.Warning, 20) 'Rein Debug hier ist bExportOrder = True
    
    	'**************************************************
            'Dienststatus geändert  
            _serviceStatus.currentState = Fix(State.SERVICE_RUNNING)
            _serviceStatus.checkPoint = 0
            _serviceStatus.waitHint = 0
            SetServiceStatus(handle, _serviceStatus)
    
            mainEventLog.WriteEntry(sAppname & " Service wurde erfolgreich gestartet.", EventLogEntryType.Information, 10)
        End Sub

    in der INIOperation wird lediglich mittels GetPrivateProfileString der Wert aus der Config.ini eingelesen und dann zugewiesen.

    in der mainTimer_Elapsed Event Methode

        Protected Sub mainTimer_Elapsed(sender As Object, e As Timers.ElapsedEventArgs)
    
    
            mainEventLog.WriteEntry(sAppname & " Service, mainTimer_Elapsed Wert der Variable bExportOrder = " & bExportOrder, EventLogEntryType.Warning, 20) 'auch hier ist bExportOrder = True
            mainEventLog.WriteEntry(sAppname & " Service, Abfrage und Sende Zyklus erreicht, prüfe auf notwendige eMails.", EventLogEntryType.Information, 10)
            export.generateMailOrderExport(1)
    
        End Sub

    in der Event Methode wird nun export.generateMailOrderExport(1) aufgerufen.

        Public Sub generateMailOrderExport(ByVal orderform As Integer)    'ByVal orderArray() As String,
    
    
            mainEventLog.WriteEntry(sAppname & " Service generateMailOrderExport Wert der Variablen bExportOrder = " & bExportOrder, EventLogEntryType.Warning, 20)
    
    End Sub

    hier ist nun bExportOrder = False. Bis egal was ich probiert habe Me.bExportOrder usw.

    Aber ich den Fehler nich ganz, wenn bExportOrder nicht existieren würde, sollte der Compiler meckern, tut
    er aber nicht. Der Dienst lässt sich 1A kompilieren ohne Fehler oder Warnungen, er lässt sich starten, beenden

    neu starten ohne Probleme, er gibt im Windows EventLog Application auch alles aus. Deshalb bin ich etwas irritiert.




    VG Daniel

    Donnerstag, 1. November 2018 14:31
  • Ah genau auch signature.generatedSignature() wird komplett durchlaufen und im Application Log lass ich mir die rtf Datei die eingelesen wurde auch ausgeben und auch die wird in einer globalen Variablen vom Typ String gespeichert, ich hab nur noch nicht versucht sie zu verwenden, aber anhand der Event Log Einträge war das speichern erfolgreich, den die greif ich genau dazu ab.

    VG Daniel


    • Bearbeitet steel2310 Donnerstag, 1. November 2018 14:35
    Donnerstag, 1. November 2018 14:35
  • Hi,
    ich würde als Erstes mal Option Strict On setzen (am besten für's gesamte Projekt), um zu verhindern, dass implizite Typkonvertierungen unerwartete Ergebnisse liefern.

    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    Donnerstag, 1. November 2018 15:46
  • Hallo Peter,
    habe ich gemacht, danke für den Hinweis, aber das löst das Problem leider nicht.

    Ich bin aber schon ein kleines Stk. weiter gekommen. den bei Aufruf von
    signature.generatedSignature() wird zuerst in der Methode geprüft ob die
    Datei vorhanden ist. Ist das der Fall, wird eine andere Methode der Klasse
    readSignature() aufgerufen, die die Datei einliest und zurückgibt an
    generatedSignature(). Dort wird der zurückgegebene Wert dann in sSignature
    die ebenfalls global in der mainService definiert ist gespeichert und das
    funktioniert. Wenn ich mir nach der Zuweisung
    sSignature ins Eventlog schreiben
    lasse steht alles tip top drin.


    VG Daniel

    Freitag, 2. November 2018 08:42
  • Hallo Daniel,

    wie soll in der Instanz "export" der Klasse "clsExport" der Wert der Variablen "bExportOrder" einer komplett anderen Instanz irgendeiner anderen Klasse zur Verfügung stehen?

    Ich denke, Du verwechselst da ziemlich vieles bzw. hast etwas komplett falsch verstanden.

    Vererbung/Inherits bezieht sich nur auf die Deklaration von Variablen, Eigenschaften, Methoden.

    Public Class A
    
        Public Property X
    
        Public Function Y( ByVal Z As Int64 )
            Return Z * 2
        End Sub
    
    End Class
    
    Public Class B
    
        Inherits A
    
        Public Function Z()
            Return MyBase.Y( 1 )
        End Sub
    
    End Class
    

    Die Instanzen sind aber dennoch komplett getrennt.

    Dim a1 As New A()
    Dim a2 As New A()
    Dim b1 As New B()
    Dim b2 As New B()

    Letztendlich hast Du hier vier völlig voneinander unabhängige Instanzen. Die Zuweisung von Werten zu den Eigenschaften der jeweiligen Instanz beeinflussen nicht die Werte der anderen Instanzen.

    D.h. Du musst entweder die Werte an die jeweilige Instanz übergeben oder Du arbeitest bspw. mit statischen Eigenschaften (Shared in VB.NET) oder anderen Elementen, die man übergreifend abfragen kann.

    BTW: Mir will sich nicht wirklich erschließen, warum Du clsExport von einer Service Klasse ableiten willst? Das eine hat doch mit dem anderen rein gar nichts zu tun?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Freitag, 2. November 2018 09:29
    Moderator
  • Hallo Stefan,
    da hast du mich ein wenig falsch verstanden, macht nix ich habs mittlerweile hin bekommen über ein Modul, aber ableiten von mainService bei der clsExport, macht in dem Fall schon Sinn, ansonsten könnte ich ja keine Methoden der mainService nutzen wie Eventlog, FileExists, die ja nur in der MainService drin stehen.

    Besten Dank!


    VG Daniel

    Freitag, 2. November 2018 12:14
  • Hallo Daniel,

    ne, ich glaube nicht, dass ich dich falsch verstanden habe, eher andersrum.

    aber ableiten von mainService bei der clsExport, macht in dem Fall schon Sinn, ansonsten könnte ich ja keine Methoden der mainService nutzen wie Eventlog, FileExists, die ja nur in der MainService drin stehen.

    Das alleine ist für mich schon ein Designfehler. Sowas hat in der Service Klasse eigentlich gar nichts zu suchen. Und ableiten musst Du für die Nutzung der Methoden auch nichts

    Erstell dir eine eigene Klasse mit den gewünschten (Hilfs-)methoden. Die kannst Du dann entweder statisch aufbauen (ob das sinnvoll ist oder nicht, kommt aber drauf an, was genau da drin ist) oder in deinen anderen Klassen jeweils neu instanzieren. Ob das nun als Eigenschaft in den Klassen gemacht wird oder on demand als lokale Variable kommt drauf an, wann und wo Du diese Sachen nutzen willst.

    So oder so: Dein Konzept ist IMHO ziemlich verworren und hat einige grundlegende Fehler, die schon in deinen Überlegungen beginnen.

    Das hat auch nichts mit Dienst oder kein Dienst zu tun, die grundlegenden Kenntnisse objektorientierter Programmierung sollten schon da sein. Daher würde ich dazu raten, sich erst einmal damit zu befassen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Freitag, 2. November 2018 12:57
    Moderator