System.UnauthorizedAccessException bei eigenem Dienst

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Drahuverar.

    System.UnauthorizedAccessException bei eigenem Dienst

    Hallo zusammen,
    für die Abfrage von Temperatur Messwerten habe ich mir einen eignene Dienst erstellt.
    Der Dienst wird als LocalSystem installiert und soll alle 15 Minuten die Messwerte in ein DataSet schreiben. Der Pfad zum Dataset liegt auf einem Netzlaufwerk.
    Das Netzlaufwerk ist im Netzwerk frei gegeben und System hat Vollzugriff, genauso wie der angemeldete User auf dem der Dienst läuft.
    Leider erhalte ich obige Exeption wenn das Dataset gespeichert werden soll.
    Wie kann ich dies beheben? Welche Codes braucht ihr dafür von mir?
    Danke Euch
    Grüße
    Micha
    "Hier könnte Ihre Werbung stehen..."
    @Drahuverar die Datei existiert noch nicht und wird beim ersten Speichern erstellt.
    hier mal die komplette Service Klasse
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "FileHeader"
    2. #If False Then
    3. Klasse für den Windows Dienst zur kontinuirlichen Abfrage der Messdaten
    4. und Speicherung in einem DataSet
    5. #End If
    6. Imports Connection.Measurement
    7. Imports System.IO
    8. #End Region
    9. Public Class MeasurementService
    10. Private _TSTimer As Timers.Timer
    11. Private _MNServer As New MeasureServer("MN-TempServer", "10.21.89.246", 4000)
    12. Private _MeasureCon As New MeasureConnection(_MNServer)
    13. Private dsTempMon As New dsMNServer
    14. Private _DataDate As String = Date.Now.Year.ToString
    15. Private _DataPath As String = "\\hq-dp01\Daten\mnKK"
    16. Private _DataFile As New FileInfo(_DataPath & "\dsTemp." & _DataDate)
    17. Protected Overrides Sub OnStart(ByVal args() As String)
    18. _TSTimer = New Timers.Timer With {.Interval = 900000, .Enabled = True}
    19. AddHandler _TSTimer.Elapsed, AddressOf OnTimerElapsed
    20. LoadDataSet(dsTempMon)
    21. End Sub
    22. Protected Overrides Sub OnPause()
    23. _TSTimer.Enabled = False
    24. End Sub
    25. Protected Overrides Sub OnContinue()
    26. _TSTimer.Enabled = True
    27. End Sub
    28. Protected Overrides Sub OnStop()
    29. _TSTimer.Enabled = False
    30. _TSTimer.Dispose()
    31. SaveDataSet(dsTempMon)
    32. End Sub
    33. Protected Sub OnTimerElapsed(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs)
    34. Dim mydate As Date = Date.Now
    35. Dim srvTemp As Double = GetMeasuredValue("pcmeasure.com1.1")
    36. Dim elekTemp As Double = GetMeasuredValue("pcmeasure.com1.2")
    37. dsTempMon.Messung.AddMessungRow(CDate(mydate.ToShortDateString), CDate(mydate.ToShortTimeString), "Serverraum", srvTemp)
    38. dsTempMon.Messung.AddMessungRow(CDate(mydate.ToShortDateString), CDate(mydate.ToShortTimeString), "Elektroraum", elekTemp)
    39. SaveDataSet(dsTempMon)
    40. End Sub
    41. Private Function GetMeasuredValue(ByVal comPort As String) As Double
    42. Dim measureValue As MeasuredValue = _MeasureCon.ReceiveMeasuredValue(comPort)
    43. If measureValue IsNot Nothing AndAlso measureValue.IsValid Then Return measureValue.MeasuredValue Else Return Nothing
    44. End Function
    45. Private Sub LoadDataSet(ByVal myDS As DataSet)
    46. myDS.Clear()
    47. If _DataFile.Exists Then
    48. myDS.ReadXml(_DataFile.FullName)
    49. End If
    50. End Sub
    51. Private Sub SaveDataSet(ByVal myDS As DataSet)
    52. myDS.WriteXml(_DataFile.FullName)
    53. myDS.AcceptChanges()
    54. End Sub
    55. End Class
    "Hier könnte Ihre Werbung stehen..."
    Wenn die Datei nicht Schreibgeschützt ist muss es an der Berechtigung liegen, sicher das alles stimmt?
    Verpacke deinen Backgroundworker mal in eine normale Anwendung (.exe) und schau was er macht.
    Wer führt den Dienst aus, dein Rechner oder ein Rechner/Server im Netzwerk?
    Hast du den Dienst auch über die Konsole installiert bzw. installieren lassen bei dem jeweiligen Gerät?


    Edit: Backgroundworker ist nicht gleich Service- mein Fehler.
    Versuch mal eine Datei von Hand dort zu erstellen- funktioniert das denn?


    Gruß,
    Drahuverar

    Option Strict On!

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Drahuverar“ ()

    Hi @Drahuverar. Hab es gelöst.
    Ich installiere den Dienst nun als Userdienst. Bei der Installation wird ein Username und Kennwort verlangt, das gebe ich ein und schon läuft alles so wie es soll :)
    Der Dienst soll auf einem Server im Netzwerk laufen damit die Messwerte kontinuirlich gespeichert werden können. ( Langzeittest steht noch aus :) ).
    Zum Projekt gehört noch eine Windows Exe, die wird von verschiedenen Mitarbeitern gestartet, die die Messwerte benötigen. Die Exe öffnet die Datei und lädt sie in ein Dataset.
    Änderungen sind nicht erlaubt und gespeichert wird da auch nix mehr. es gibt lediglich einen Button für NeuLaden (die Werte ändern sich ja alle 15 Minuten).
    Das ganze löst eine alte Anwendung ab, die noch unter XP läuft (und das mehr schlecht als Recht). Da die Temperaturfühler aber alle über Netzwerk angeschloßen sind, kann ich so einfacher die Daten abfragen.
    Danke Dir
    "Hier könnte Ihre Werbung stehen..."
    Ich muss mich mal kurz korrigieren.... es funktioniert garnicht :-(.
    • Also, der Dienst wird als Userdienst installiert, das funktioniert.
    • Der Dienst wird gestartet, das funktioniert auch ohne Fehler.
    • Der Dienst kann gestoppt werden, das funktioniert und die Datei aufm Laufwerk wird angelegt (oder aktualisert wenn schon da.) das funktioniert also auch.
    • Was garnicht funktioniert ist das rein schreiben in die Datei... ich vermute, das der Timer nicht gestartet wird und daher das Timer.Elapsed Event nicht gefeuert wird.
    Kann da mal jemand drüber gucken, wo das Problem ist?
    ich lade das komplette Projekt mal hoch (siehe Anhang)
    Dateien
    • TempControl01.zip

      (53,02 kB, 115 mal heruntergeladen, zuletzt: )
    "Hier könnte Ihre Werbung stehen..."
    Lese ich das richtig?

    "... das funktioniert und die Datei aufm Laufwerk wird angelegt (oder aktualisert wenn schon da.) das funktioniert also auch." ?

    Wenn die Datei angelegt wird und du dann Schreibst kann es sein dass es nicht Funktioniert weil du die Datei noch offen hast, in dem fall hinter der zeile wo die datei erstellt wird ein .Dispose()

    lg
    Begeisterter BF4 Spieler :D
    Hallo @Gangsterkrafter.
    Das Problem mit der Datei schließe ich jetzt erstmal aus, ich denke erstmal, das das Timer.Elapsed Event nicht gefeuert wird, dann ist auch klar das nichts passiert.
    Wenn ich den Dienst stoppe, soll er ja das DataSet speichern (siehe OnStop_Event).
    Ich habe mir eben auch mal ein Testprojekt erstellt, die gleiche Connection Klasse verwendet, im groben die gleichen Komponenten verwendet (nur eben als WinForm)
    und DORT funktioniert das ganze bestens.
    Code von TestProjekt Form

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private _MNServer As New MeasureServer("MN-TempServer", "10.21.89.246", 4000)
    3. Private _MeasureCon As New MeasureConnection(_MNServer)
    4. Private _DataDate As String = Date.Now.Year.ToString
    5. Private _DataPath As String = "\\hq-dp01\Daten\mnKK"
    6. Private _DataFile As New FileInfo(_DataPath & "\dsTemp." & _DataDate)
    7. Private Sub btnFetch_Click(sender As Object, e As EventArgs) Handles btnFetch.Click
    8. txtServer.Text = GetMeasuredValue("pcmeasure.com1.1").ToString
    9. Dim mydate As Date = Date.Now
    10. Dim srvTemp As Double = GetMeasuredValue("pcmeasure.com1.1")
    11. Dim elekTemp As Double = GetMeasuredValue("pcmeasure.com1.2")
    12. DataSet1.Messung.AddMessungRow(CDate(mydate.ToShortDateString), CDate(mydate.ToShortTimeString), "Serverraum", srvTemp)
    13. DataSet1.Messung.AddMessungRow(CDate(mydate.ToShortDateString), CDate(mydate.ToShortTimeString), "Elektroraum", elekTemp)
    14. SaveDataSet(DataSet1)
    15. End Sub
    16. Private Function GetMeasuredValue(ByVal comPort As String) As Double
    17. Dim measureValue As MeasuredValue = _MeasureCon.ReceiveMeasuredValue(comPort)
    18. If measureValue IsNot Nothing AndAlso measureValue.IsValid Then Return measureValue.MeasuredValue Else Return Nothing
    19. End Function
    20. Private Sub LoadDataSet(ByVal myDS As DataSet)
    21. myDS.Clear()
    22. If _DataFile.Exists Then
    23. myDS.ReadXml(_DataFile.FullName)
    24. End If
    25. End Sub
    26. Private Sub SaveDataSet(ByVal myDS As DataSet)
    27. myDS.WriteXml(_DataFile.FullName)
    28. myDS.AcceptChanges()
    29. End Sub
    30. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    31. LoadDataSet(DataSet1)
    32. End Sub


    Sceenshot:
    "Hier könnte Ihre Werbung stehen..."
    Die maximale Ausführungszeit für den Code in den Service-Events (OnStart, OnStop...) liegt bei 15 sec.
    Deswegen ist mein übliches Vorgehen in OnStart erst mal nur einen Thread zu starten, der die Hauptarbeit übernimmt.
    Wie lange dauert denn ​LoadDataSet(dsTempMon)?

    Ausserdem empfehle ich, eine Solution zu bauen mit zwei alternativen Start-Projekten und einer DLL.
    Eines für den Service, ein Winforms-Projekt zum interaktiven Testen.
    Das Winforms-Projekt hat nur zwei Buttons (Start und Stop).
    Aus beiden Projekten wird die StartRoutine der DLL aufgerufen, in der die ganze Intelligenz läuft.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hm... echt Komisch, Hast du denn Schonmal Probiert den Code in einem Button Auszufueheren, um sichergehen zu Koennen dass definitiv das Timer.Elapsed Event Probleme Macht?

    Wenn das mit dem Button Funktioniert, Liegt es Definitiv am Timer.Elapsed .
    Wenn aber, der Code mit dem Button nicht Funktioniert, dann Kann es sein dass irgentwo im Code ein Dummer Fehler ist, welcher so einfach ist dass du (so ist es immer bei mir) 3tage Brauchst, um zu Bemerken was du/ich eigentlich fuer einen Dummen Fehler gemacht haben :D


    lg
    Begeisterter BF4 Spieler :D
    Hallo,
    was soll ich sagen, es funktioniert!
    Nachdem ich gestern schon am verzwifeln war, hab ich gestern Abend das Projket mal als Konsolenanwendung gebaut, dort funktionierte es dann acuh nicht :(
    Dann habe ich mir den MSDN Artikel noch einmal komplett durch gelesen diesen hier und hab das Beispiel genau so nachgestellt. Das funktionierte. Dann bin ich Zeile für Zeile durch meinen Code und hab geguckt was falsch sein könnte. Und ob ihr es glaubt oder nicht, die einzigste Änderung, die ich gemacht habe war:

    _TSTimer = New Timer zu ändern in _TSTimer = New Timer()

    und siehe da... es läuft.

    Nun hab ich noch ein paar Sachen umgebaut, 2. Dataset im Service gelöscht, das DataSet global zur Verfügung gestellt und den Timer Intervall auf 15 Minuten gestellt.
    Der Dienst wird als User installiert, Username und Kennwort bei der Installation vergeben und schon rennt es.

    Danke an alle
    P.S. ich hänge das komplette Projekt nochmal dran, so wie es da ist funktioniert es bestens.
    Dateien
    • TempControl03.zip

      (46,79 kB, 105 mal heruntergeladen, zuletzt: )
    "Hier könnte Ihre Werbung stehen..."