Announcement

Collapse
No announcement yet.

Process.HasExited

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Process.HasExited

    Hi zusammen,

    Ich habe da gerade ein großes Problem: Ich versuche in einer Schleife Acrobat abzuschießen, indem ich dem Programm so oft WM_CLOSE schicke, bis pro.HasExited True meldet:

    [highlight=vbnet]
    Public Sub PDFDrucken(ByVal pFilename As String)

    Try
    Dim f As String = IIf(InStr(pFilename, " ") > 0, Chr(34) & pFilename & Chr(34), pFilename)
    Dim starter As New ProcessStartInfo(GetPDFPrintExe(), " /p /h " & f) '"/T " & f
    Dim pro As New Process

    pro.StartInfo = starter
    pro.StartInfo.UseShellExecute = True
    pro.Start()
    Wait(5)

    Dim hAcrobatWindow As IntPtr
    Do
    hAcrobatWindow = pro.MainWindowHandle
    If hAcrobatWindow = 0 Then Exit Do 'Prozess hat kein Fenster (mehr) -> Prozess ist bereits beendet
    If PostMessage(hAcrobatWindow, WM_CLOSE, 0, 0) = 0 Then
    clsLog.LogLine("PostMessage an AcrobatReader fehlgeschlagen:" & Err.LastDllError & " - " & Err.Description)
    End If
    pro.WaitForExit(1000)
    Loop While Not pro.HasExited

    Catch ex As Exception
    ShowError("Ein Fehler ist aufgetreten:" & ex.Message & vbCrLf & ex.StackTrace)
    Finally
    'Speicher aufräumen
    GC.Collect()
    GC.WaitForPendingFinalizers()
    End Try
    End Sub
    [/highlight]

    Das pro.WaitForExit(1000) habe ich hinzugefügt, weil das PostMessage bei einigen Anwendern immer mit Fehler 1816 zurückgekommen ist, nun habe ich heute die Meldung von einem dieser Anwender zurückbekommen, es würde eine Fehlermeldung zurückgegeben "Process has exited, so the requested information is not available". Der Screenshot sagt mir, der Fehler käme beim ensureState der Funktion get_MainWindowHandle, was heisst, dass entweder hasExited False zurückgegeben hat, obwohl der Prozess schon beendet war, oder sich Acrobat zwischen Schleifenende und erneutem Schleifendurchlauf beendet hat.

    Wie umgehe ich diesen Fehler? Ich kann ja schon aus Ressourcengründen wohl schlecht um das pro.MainWindowHandle nochmal einen try-catch Block herumsetzen, mal davon abgesehen, dass wenn ich den Fehler ja eigentlich vermeiden will, wenn er aber zwischen While not pro.HasExited und pro.getMainWindow dazwischen kommt, dann kann er auch zwischen einen if not pro.hasExited und pro.MainWindowHandle den Status ändern.

    Nebenfrage: Wenn ich Acrobat mit entsprechendem Befehl geöffnet habe, und nicht 5 Sekunden vor der Schleife warte, sondern ein WaitForInputIdle nutze, ist das dann bis Acrobat soweit gestartet hat, dass er anfangen kann zu drucken, oder bis der Druck beendet ist?

    Gruß
    Martin
    Attached Files

  • #2
    Hallo,

    warum verwendest du das nicht als ActiveX?

    Sonst gibts auch die Hammer-Mtehode Process.Kill


    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Dein Errorhandling schnappt sich einfach alle Exceptions und zeigt die an.
      Process.MainWindowHandle wirft eine InvalidOperationException wenn der Prozess bereits weg ist. Also diesen Exceptiontyp einfach durch winken und nicht melden.

      Comment


      • #4
        Mag ja sein, dass ich da einem Fehler aufliege aber bei einer ActiveX-Komponente bin ich doch auf eine bestimmte Version festgelegt, also die Version, die zum Zeitpunkt der Kompilierung vorhanden war, was bedeutet, wenn dann in einem Jahr plötzlich Acrobat Version 23 Funktionen in PDFs reinbaut, die mit der momentanen Version 9 nicht geöffnet werden können, außerdem müsste ich dann sicherstellen, dass entsprechende Programme installiert sind (also definitiv Adobe Acrobat und Reader unterscheiden)

        Ein brutaler Abbruch mit Kill könnte ich nur machen, wenn ich sichergehen kann, dass der Druckauftrag bearbeitet ist, das kann ich aber nur, wenn der Adobe Reader das von sich aus bestätigt (also indem er auf WM_CLOSE endlich reagiert, deshalb sende ich auch ein WM_CLOSE und kein WM_QUIT) daher auch die entsprechenden Fragen in meinen anderen Thread, der mehr auf den Acrobat Reader bezogen war.

        Den Fehler zu ignorieren (bzw. nur stumm zu protokollieren) ist zwar auch eine Möglichkeit. Wird der Fehler denn wirklich nur erzeugt, wenn der Prozess schon tot war, oder gibt es auch Situationen, in denen dann ein Handeln nötig wäre (z.B. um zu verhindern, dass ein Zombie-Prozess übrigbleibt, der weitere Drucke behindern würde)?

        Gruß
        Martin

        Comment


        • #5
          Mag ja sein, dass ich da einem Fehler aufliege aber bei einer ActiveX-Komponente bin ich doch auf eine bestimmte Version festgelegt, also die Version, die zum Zeitpunkt der Kompilierung vorhanden war,
          Darauf habe ich dich schon am 23.09. hingewiesen: http://entwickler-forum.de/showthread.php?p=205186#post205186 Schau's dir mal an.


          mfG Gü
          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

          Comment


          • #6
            Mag ja sein, dass ich da einem Fehler aufliege aber bei einer ActiveX-Komponente bin ich doch auf eine bestimmte Version festgelegt, also die Version, die zum Zeitpunkt der Kompilierung vorhanden war, was bedeutet, wenn dann in einem Jahr plötzlich Acrobat Version 23 Funktionen in PDFs reinbaut, die mit der momentanen Version 9 nicht geöffnet werden können, außerdem müsste ich dann sicherstellen, dass entsprechende Programme installiert sind (also definitiv Adobe Acrobat und Reader unterscheiden)
            Ich weiß nicht ob die COM-Version besser wäre aber deine Argumentation könnte man auf die Kommandozeilenoptionen genauso anwenden. Welche Sicherheit hast du das sich die nicht ändern oder bei allen PDF Viewern gleich sind? Deine jetzige Version ist aber definitiv auch schon Adobe Reader spezifisch.

            Den Fehler zu ignorieren (bzw. nur stumm zu protokollieren) ist zwar auch eine Möglichkeit. Wird der Fehler denn wirklich nur erzeugt, wenn der Prozess schon tot war, oder gibt es auch Situationen, in denen dann ein Handeln nötig wäre (z.B. um zu verhindern, dass ein Zombie-Prozess übrigbleibt, der weitere Drucke behindern würde)?
            Die Doku sagt das es so ist. Die Entscheidung ob die vertrauenswürdig ist überlas ich dir. Du kannst ja im Exceptionhandler selbst nochmal auf HasExited testen, wenn die nein sagt kannst du deinen Prozess immer noch um Hilfe rufen lassen.

            Comment


            • #7
              Originally posted by gfoidl View Post
              Darauf habe ich dich schon am 23.09. hingewiesen: http://entwickler-forum.de/showthread.php?p=205186#post205186 Schau's dir mal an.


              mfG Gü

              Ich habe den Artikel, den Du verlinkt hast sehr wohl gesehen, auch den Artikel, der dort verlinkt wird, und da sagt der Autor selbst, dass die Information in der Form unvollständig ist, und nur funktioniert, wenn die 32-Bit variante installiert ist. Da der Kommandozeilenaufruf aber in allen Versionen gleich ist (und vermutlich länger gleich bleibt als die CLSID), hatte ich entschieden den Kommandozeilen-Ansatz weiterzuverfolgen.

              Hinzu kommt, dass ich mir auch das Beispiel-Projekt von Rainbird heruntergeladen habe, weil in keinem der Artikel so richtig der Umgang erklärt wird, ich also in der Verwendung innerhalb des Projektes das nachlesen wollte, und das ganze schon daran hängengeblieben ist, dass ich das Projekt nicht öffnen kann, weil es für eine spätere Version von Visual Studio geschrieben wurde (ich arbeite mit VS 2005), und die Sourcen Namespaces importieren, die mein Visual Studio nicht einmal kennt, ich kann also nicht davon ausgehen, dass dieser Ansatz in meiner Umgebung überhaupt umsetzbar ist, und dass ich keinen Einfluss auf die Computerumgebung habe (weder Entwicklung noch Anwendung) habe ich glaube ich schon öfters erwähnt.

              Wenn der Hinweis am 23:09 12:31 geholfen hätte, hätte ich mich ebenfalls in meinem Artikel am 23.09 um 14:12 dafür bedankt, und ich hielte es vor 2 Tagen noch für unsinnig, für eine ein-Zeilen Antwort eine derart umfangreiche "Geht nicht"-Antwort zu schreiben wie jetzt nachgezogen, andererseits kann ich auf Kommentare "Das habe ich Dir bereits gesagt, sieh nochmal nach!" durchaus verzichten, also werde ich möglicherweise so etwas in Zukunft doch tun.


              OK, zurück zum sachlichen.

              Ich hatte schon häufiger, gerade von Microsoft, unvollständige Dokumentationen, oder sogar definitiv falsche. Die Dokumentation selbst sagt aber auch nur "wenn dieses Problem besteht, dann kommt diese Exception". Daraus "Wenn diese Exception kommt, besteht dieses Problem" zu schließen ist mehr als gefährlich (vergleiche "... also war Sokrates eine Katze"), deswegen wollte ich mich nochmal vergewissern, bevor ich einen schwereren Fehler wie "Fenster existiert nicht, weil der PDF-Druck gar nicht erst starten konnte" ignoriere, weil ich glaube es kann nur der "Fenster existiert nicht, weil Prozess eh schon tot ist" sein, und damit mehr kaputtmache. Ich werde es einfach so probieren, der Fehler selbst wird ja im Logfile vermerkt, falls es Probleme gibt, ist dies also nachvollziehbar. Ich kann es halt die nächsten 2 Wochen nicht selbst nachverfolgen, weil ich in Urlaub bin, deshalb wollte ich das vorher absichern.

              Warum der Ansatz Acrobat Reader-spezifisch sein soll, verstehe ich allerdings nicht so ganz. Auch Adobe Acrobat 3D reagiert auf diese Kommandozeile genauso wie der Reader, hier hat Adobe also für einen Aufrufstandard gesorgt, der vermutlich auch lange Zeit so erhalten bleibt (vergleichbar an der Entscheidung von Windows, das zugeordnete Programm an der Endung festzumachen statt direkt in den Dateiinfos zu speichern). Sicherheit habe ich diesbezüglich zwar nicht, aber da vertraue ich einfach auf Adobe, dass sie wenn sie einmal etwas für alle Produkte festgelegt haben, dies nur bei schweren Problemem ändern würden, und Kommandozeilenparameter an sich werden ja wohl erhalten bleiben, es sei denn Microsoft ändert das in Windows, dann ist der PDF-Druck aber das geringste Problem...

              Bis demnächst
              Martin

              Comment


              • #8
                Wenn der Hinweis am 23:09 12:31 geholfen hätte, hätte ich mich ebenfalls in meinem Artikel am 23.09 um 14:12 dafür bedankt, und ich hielte es vor 2 Tagen noch für unsinnig, für eine ein-Zeilen Antwort eine derart umfangreiche "Geht nicht"-Antwort zu schreiben wie jetzt nachgezogen,
                Du hättest nur erwähnen brauchen dass dir das nicht hilft. So bin ich davon ausgegangen dass du es übersehen hast.
                andererseits kann ich auf Kommentare "Das habe ich Dir bereits gesagt, sieh nochmal nach!" durchaus verzichten, also werde ich möglicherweise so etwas in Zukunft doch tun.
                Ich werde in Zukunft einfach dir nicht mehr versuchen zu helfen dann brauchst du auf meine Antworten auch nicht reagieren

                mfG Gü
                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                Comment


                • #9
                  Warum der Ansatz Acrobat Reader-spezifisch sein soll, verstehe ich allerdings nicht so ganz.
                  Ich habe auf die '/p /h' Kommandozeilenoptionen angespielt die werden wohl nur Adobe Produkte so kennen.

                  hier hat Adobe also für einen Aufrufstandard gesorgt,
                  Guck mal hier. Folgendes Zitat des Adobe Supports zu den Kommandozeilenoptionen

                  These are unsupported but have worked for some developers.
                  Sehr Vertrauen erweckend

                  Comment

                  Working...
                  X