Service ruft externes Programm nicht auf

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Service ruft externes Programm nicht auf

    Ich habe einen Code welcher als VB.NET über einen button aufgerufen funktioniert.
    Es muss allerdings ein Service sein. Beim Service hört er aber dort auf, wo er den Process starten soll.


    Spoiler anzeigen
    Public Class Service1

    VB.NET-Quellcode

    1. Public Shared XDoc1 As XDocument = XDocument.Load("C:\mqcit\mqcitconfig.xml") 'Laden der XML-Config-Datei
    2. Public Shared logpath As String = (XDoc1.<mqcit>.<config>.<logpath>.Value) 'Laden des Logpfad
    3. Public Shared docpath As String = (XDoc1.<mqcit>.<config>.<docpath>.Value) 'Pfad für die Worddatei
    4. Public Shared maxlogsize As Integer = (XDoc1.<mqcit>.<config>.<maxlogsizebyte>.Value) 'Maximale Größe der Log Datei in Byte
    5. Public Shared timertime As Integer = (XDoc1.<mqcit>.<config>.<timermilliseconds>.Value) 'Wie oft soll das Programm aufgerufen werden, in Millisekunden
    6. Public Shared Message As String 'Variable für Logmessage
    7. Public Shared alreadyrun As Boolean = False 'Läuft der Ablauf bereits?
    8. Protected Overrides Sub OnStart(ByVal args() As String)
    9. Timer1.Interval = timertime
    10. Timer1.Start()
    11. End Sub


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Sub OpenDocuments()
    2. If alreadyrun = False Then
    3. alreadyrun = True
    4. Try
    5. ' Zunächst wird nach einem Worddokument gesucht
    6. Dim file As String
    7. Dim oDir As New System.IO.DirectoryInfo(docpath) '...wird der Ordner zum auslesen vorbereitet
    8. Dim oFiles As System.IO.FileInfo() = oDir.GetFiles() '...werden alle Dateien ausgelesen
    9. Dim oFile As System.IO.FileInfo '...wird eine Datei gelesen
    10. For Each oFile In oFiles '...für jedes file wird überprüft...
    11. If oFile.Extension = ".docx" Or oFile.Extension = ".doc" Then '....ob es die Endung doc oder docx hat, wenn ja...
    12. file = oFile.FullName 'wird der Dateipfad mit Datei in der Variablen file gespeichert.....
    13. Message = ("Folgende Datei wird bearbeitet: " & oFile.Name) 'und eine Meldung ausgegeben.
    14. Writemessage(Message)
    15. Exit For
    16. End If
    17. Next
    18. 'Nun wird das Worddokument aufgerufen
    19. If Not file Is Nothing Then 'Zunächst wird überprüft, ob überhaupt eine Datei gefunden wurde
    20. 'Ausführen und beenden des Prozesses Word
    21. Dim prozess As New Process
    22. prozess = Process.Start(file) 'falls ja wird der Prozess gestartet also Word geöffnet und zum Überwachen in der Variable prozess gespeichert
    23. While prozess.HasExited = False 'solange der Prozess offen ist wird nichts getan.
    24. Continue While
    25. End While
    26. If prozess.HasExited = True Then 'wenn der Prozess beendet wurde, wird überprüft ob der Prozess keine Fehler gemeldet hat und eine entsprechende Meldung ausgegeben.
    27. If prozess.ExitCode = 0 Then
    28. Message = (file & " wurde erfolgreich importiert.")
    29. Writemessage(Message)
    30. Else
    31. Message = ("Fehler beim importieren der Datei " & file)
    32. Writemessage(Message)
    33. End If
    34. DeleteDocument(file)
    35. End If
    36. End If
    37. Catch ex As Exception
    38. Message = (ex.ToString)
    39. Writemessage(Message)
    40. End Try
    41. alreadyrun = False
    42. End If
    43. End Sub



    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Sub Writemessage(ByVal logmessage As String) 'wenn die Methode Writemessage aufgerufen wird...
    2. If System.IO.Directory.Exists(logpath) = False Then 'überprüfen ob der Temp Ordner vorhanden ist
    3. System.IO.Directory.CreateDirectory(logpath) 'Falls nicht wird dieser erstellen
    4. End If
    5. If My.Computer.FileSystem.FileExists(logpath & "\log.txt") = True Then 'Wenn das Lofile schon existiert,
    6. If My.Computer.FileSystem.GetFileInfo(logpath & "\log.txt").Length >= maxlogsize Then 'wird überprüft ob die maximale Loggröße erreicht ist
    7. My.Computer.FileSystem.DeleteFile(logpath & "\log.txt") 'falls ja wird das logfile gelöscht.
    8. End If
    9. End If
    10. Using fw As New System.IO.StreamWriter(logpath & "\log.txt", True) 'Legt falls nicht vorhanden das Logfile an , und verbietet ggf. das Überschreiben
    11. fw.WriteLine(Now() & " " & logmessage) 'Schreibt in den Log das Datum , und die mitgegebene Message.
    12. End Using
    13. End Sub


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Sub DeleteDocument(ByVal datei As String)
    2. 'Löschen der bearbeiteten Datei
    3. If System.IO.File.Exists(datei) Then 'Prüfen ob die Datei noch existiert
    4. My.Computer.FileSystem.DeleteFile(datei) 'Datei löschen
    5. If System.IO.File.Exists(datei) Then 'Prüfen ob die Datei noch existiert
    6. Message = ("Fehler beim löschen der Datei " & datei)
    7. Writemessage(Message)
    8. Else
    9. Message = (datei & " wurde erfolgreich gelöscht")
    10. Writemessage(Message)
    11. End If
    12. End If
    13. 'Löschen der temporären Dateien
    14. Dim aDir As New System.IO.DirectoryInfo(docpath) '...wird der Ordner zum auslesen vorbereitet
    15. Dim aFiles As System.IO.FileInfo() = aDir.GetFiles("~$*") '...werden alle Dateien ausgelesen
    16. Dim aFile As System.IO.FileInfo '...wird eine Datei gelesen
    17. For Each aFile In aFiles
    18. My.Computer.FileSystem.DeleteFile(aFile.FullName) 'Temp Datei wird gelöscht
    19. Message = ("Die Temporäre Datei " & aFile.FullName & " wurde gelöscht.")
    20. Writemessage(Message)
    21. Next
    22. End Sub

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Protected Overrides Sub OnStop()
    2. ' Add code here to perform any tear-down necessary to stop your service.
    3. Timer1.Stop()
    4. End Sub

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
    2. OpenDocuments()
    3. End Sub
    4. End Class




    Jemand ne idee wie ich die Datei mit Word aus dem Service aufrufen kann?

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Kaze91“ ()

    1. Mach mal bitte um Deinen Code einen Expander.
    2. solltest Du im Falle eines Services Logausgaben einbauen, um den Ablauf überwachen zu können.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Kaze91 schrieb:

    Hab ich doch?
    An der interessierenden Stelle ist keiner:

    VB.NET-Quellcode

    1. prozess = Process.Start(file) 'falls ja wird der Prozess gestartet also Word geöffnet und zum Überwachen in der Variable prozess gespeichert
    2. While prozess.HasExited = False 'solange der Prozess offen ist wird nichts getan.
    3. Continue While
    4. End While
    Ich denke mal, er hängt in dieser Schleife fest.
    Generier die Process-Instance WithEvents und mach Dir ein Event, wenn der Prozess beendet wurde.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Der Code funktioniert, sollange es kein Service ist. Ich habe gedebuggt und er kommt nicht in die Schleife.

    Ich habe hier im Forum (von dem mit dem 2 Mäussen als Profilfoto^^) iwo gelesen dass es nicht möglich ist in einem Service ein externes Programm zu starten.
    Stimmt das? dann hätte ich ein Problem

    Kaze91 schrieb:

    Stimmt das?
    Weiß ich nicht. Teste es mit dem Notepad.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Dann geht es nicht.
    Was macht denn Dein Dienst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Dann musst Du es halt als Programm laufen lassen.
    Sieh Dir mal den FileSystemWatcher an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Kaze91 schrieb:

    Hat mein Chef nicht so akzeptiert^^
    Dann lass Dir von Deinem Chef ein Betriebssystem schenken, das das erlaubt. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Dass das nicht funktioniert, hat einen einfachen Grund: Dienste laufen nicht als Benutzer, sondern mit Systemrechten (= anderer Account). Sie haben daher keine Ahnung, welcher Benutzer auf welchem Desktop angemeldet ist und haben auch keine Verbindung zu irgendeiner Oberfläche. Der Word-Prozess startet nur kurz, stellt fest, dass er sein Fenster nicht erstellen kann (wo denn auch) und beendet sich sofort wieder. Vielleicht startet er auch und wird im "Nichts" erstellt (gezeichnet), sodass die Schleife zur Endlosschleife wird.

    Durch diese gewollte (und sinnvolle) Einschränkung kann ein Dienst nicht mal ne MessageBox anzeigen, weil er schlichtweg keine Fenster erstellen kann. Ich zitiere mal von Stackoverflow:
    This article explains Session 0 Isolation which among other things disallows services from creating a UI in Windows Vista/7. In your service starts another process, it starts in Session 0 and also will not show any UI. (By the way, the UI is created, it's just that Session 0 is never displayed). This article on CodeProject can help you create a process from a service on the user's desktop and show its UI.
    Gruß
    hal2000

    Kaze91 schrieb:

    Ok ich verstehe,
    Dein Chef auch? :D
    Lass einfach ein hidden Programm laufen, dass nicht in der TaskBar erscheint.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!