none
Wie kann man mit VFP feststellen, ob Outlook läuft? RRS feed

  • Frage

  • Wieder mal ich ;-))

    Hallo NG, mit folgendem Programm sende ich Daten aus VFP über Outlook. Das funktioniert eigentlich wunderbar, solange Otlook läuft:

                #DEFINE MAILITEM 0
                #DEFINE IMPORTANCENORMAL 1
                #DEFINE TRUE .T.
                #DEFINE FALSE .F.

                fhand = FOPEN(SYS(5) + SYS(2003) + "\mail\zuep1.txt")    && Mailtext laden
                mailtext = FREAD(fhand,5000)
                FCLOSE(fhand)

                oOutLookObject = CreateObject('Outlook.Application')
                oEmailItem = oOutLookObject.CreateItem(MAILITEM)

                WITH oEmailItem
                    .Recipients.Add(mitglieder.email) && Adresse, an die die Mail geschickt wird
                    .Subject = "Erinnerung Ablauf ZÜP von " + ALLTRIM(mitglieder.vorname) + " " + ALLTRIM(mitglieder.name)
                    .Importance = IMPORTANCENORMAL
                    .Body = mailtext    && Inhalt des Anschreibetextes
                    .Send
                ENDWITH

                RELEASE oEmailItem
                RELEASE oOutLookObject

    Wenn jedoch Outlook vorher nicht gestartet wurde, erhalte ich eine OLE-Fehlermeldung.

    Frage: Kann man von VFP einfach prüfen, ob Outlook läuft? Dann könnte ich entscheiden, ob ich überhaupt in diese Mailsenderoutine gehe.

    Danke und schönen Feierabend.

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Dienstag, 23. Januar 2018 18:49

Antworten

  • Hallo Jürgen, 
    ja die Antwort war nicht die beste.
    Versuche bitte GetObject. 
    So sollte das etwa aussehen:
     oOutLookObject = GetObject('Outlook.Application')

    Der Unterschied soll sein das GetObject nur eine Instanz erhält wenn denn Outlook auch offen ist.
    Danach sollst Du oOutlookObject abfragen können. 

    oder etwa so:

      TRY
    oOutLookObject  = getobject('',"outlook.application")
    Catch ....
    oOutLookObject = createobject("outlook.application")
    ENTRY

    Grüße Alexander

    Mittwoch, 24. Januar 2018 15:56
  • 1. Wenn Outlook gar nicht installiert ist, haut Dir CREATEOBJECT("Outlook.Application") ein Fehler 1733 um die Ohren, und zwar sofort. Wenn das auf einem Rechner ohne Outlook immer noch ein Objekt liefert, dann ist da was halb installiert oder halb deinstalliert. Dagegen hast Du kein Mittel, Du musst Dich auf sorgfältig verwaltete Rechner verlassen können.

    Aber natürlich kannst Du das CREATEOBJECT in TRY..CATCH machen, um den Fehler lokal abzufangen und im CATCH Bereich dann zu melden, dass Outlook nicht (sauber) installiert ist. Dito bei CREATEITEM und anderen Aufrufen, die bei sauberer Installation auch sauber funktionieren sollten.

    2. Der Recipients Fehler deutet darauf hin, dass die mitglieder.email Deinem Outlook nicht bekannt ist. Wenn ein Recipient per Recipients.Add() gesetzt wird gibt es tyischerweise einen automatischen Check mit dem Outlook Addressbuch o.ä. Wie wäre es mit ALLTRIM(mitglieder.email)? Schon alleine Leerzeichen nach dem Ende der eigentlichen Mailaddresse mögen stören, dito führende Leerzeichen.

    Nebenbei: Weswegen ich "o.ä." sagte. Wenn Outlook einmal eine Mailadresse verwendet hat, wird sie deswegen noch lange nicht in das Addressbuch eingetragen, ist aber dem Prüfmechanismus von Recipients.Add() bekannt. Irgendwo speichert Outlook da ein Systemaddressbuch o.ä.

    Einfacher ist, es oMailItem.To=ALLTRIM(mitglieder.email) zu setzen, das löst den Prüfmechanismus nicht aus. Zustellprobleme wirst Du dann mit Rückmeldungen bekommen, aber Outlook ist da raus und wirft auch diese Art von Fehler dann nicht mehr. Das Auffinden im (System)Addressbuch ist sowieso immer noch keine Garantie, eine Mailadresse kann ja jederzeit gekündigt werden und damit ungültig werden.

    3. Wenn man ein laufendes Outlook per GETOBJECT() holt und das vom Anwender gerade in einem modalen Status ist, kann Automation auch fehlschlagen, deswegen würde ich sowieso raten bei CREATEOBJECT zu bleiben. Zu NT und anfangs XP Zeiten war jeder neue Prozess immer noch eine Bürde, die u.U. auch mit zuwenig RAM ein System instabil machte, wenn man dann noch einen Prozess startete. Aber da sind wir durch.

    Mit Fehlern, die Du von unsauberen PCs hast kann man Dir nicht mit VFP Code helfen, da musst Du dann ran und neu installieren. Office365 kann seins dazu tun, wenn Outlook gar nicht als echte Desktop Anwendung installiert ist kann Outlook auch nicht so automatisiert werden.

    Nachtrag: Ich habe noch nie eine Click-To-Run Installation unter den Fittichen gehabt, bei denen Anwendungen gestreamt werden. Die Beobachtung, Office Anwendungen seien nur während sie laufen automatisierbar könnten damit zusammenhängen, wenn nur während ihres Laufs auch die entsprechende EXE als temporäre Installation vorliegt und auch nur dann für OLE Automation verfügbar ist. Was CREATEOBJECT() dann genau macht und warum es nicht sofort scheitert, wenn Outlook nicht gerade läuft kann ich nur raten. Was ich finde ist, dass Click-To-Run Installationen Typelib Informationen nicht in den HKEY_CLASSES_ROOT Zweig der Registry schreiben, sondern nur in HKEY_LOCAL_NACHINE. Das alleine würde aber einfach nur ein Scheitern des CREATEOBJECT bewirken.

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Donnerstag, 25. Januar 2018 10:21

Alle Antworten

  • Hallo Jürgen, das ist nun gefühlt hundert Jahre her das ich den Fux am wickel hatte.

    Das hier sollte dein Beispiel sein:
    http://fox.wikis.com/wc.dll?Wiki~ExcelAutomation

    Für Dich dann:

    if vartype(oOutLookObject) != "O"
    HTH

    Grüße Alexander

    Dienstag, 23. Januar 2018 19:19
  • Hallo Jürgen,

    1) Deine Programmzeilen sollten eigentlich bestens funktionieren !!!

    Mit der Zeile oOutLookObject = CreateObject('Outlook.Application') wird nämlich Outlook gestartet und unsichtbar in den Speicher geladen! Outlook muß deshalb noch garnicht laufen. Genauso mache ich es auch.

    Ich würde mal Deine Programmzeilen im Debugger Zeile für Zeile laufen lassen und nach der Zeile oOutLookObject = CreateObject('Outlook.Application') mal im Taskmanager nach Microsoft Outlook / Outlook.exe suchen.

    Das sollte dann im Abschnitt Hintergrundprozesse aufgelistet sein.

    2) wie lautet die OLE-Fehlermeldung genau ???

    Außerdem würde ich im Debugger alle beteiligten Programmzeilen Zeile für Zeile durchlaufen, um herauszufinden, welche Zeile den OLE-Fehler erzeugt !!!

    Gruß, Stefan



    Dienstag, 23. Januar 2018 20:00
  • Hallo Jürgen,

    ich pflichte Stefan bei. Wie er schon erklärt hat startet CreateObject('Outlook.Application') eine neue Outlookinstanz, egal ob Outlook schon läuft oder nicht. Ein Unterschied dürfte sein, wie schnell sich dann ein weiteres Outlook "öffnet".

    Ich hatte nur einmal mit solchen Phänomenen in Excel 2007 zu tun, irgendetwas hat sich in der Automatisierungsebene getan, was dazu führt, dass einem OLE Client (wie Du in dem Moment von VFP Seite her bist) noch nicht vollständig initialisierte Objekte bereitgestellt werden, deren Methoden dann nicht funktionieren, wenn man nicht noch etwas wartet.

    Ich tippe darauf, alles wird laufen, wenn Du debuggst und dann Outlook genug Zeit hat, vollständig initialisiert zu sein, wenn Du zu CreateItem kommst. Und ich tippe darauf, in der Zeile kriegst Du den OLE Fehler im Moment.

    Was dagegen helfen würde ist ein DOEVENTS FORCE nach dem CreateObject('Outlook.Application').

    Aber es gäbe noch völlig normale Gründe, z.B.NULL Werte in Deinen mitglieder-Daten, die dann dazu führen, dass Du dem Subject des Mailitems NULL zuweist.

    Ich würde daher um nichts anderes beten als Stefan, geh das im Debugger in Einzelschritten durch. Es hilft auch ein Errorhandling zu haben um die den Fehler werfende Zeilennummer zu haben.

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Mittwoch, 24. Januar 2018 09:31
  • Hallo Jürgen, das ist nun gefühlt hundert Jahre her das ich den Fux am wickel hatte.

    Das hier sollte dein Beispiel sein:
    http://fox.wikis.com/wc.dll?Wiki~ExcelAutomation

    Für Dich dann:

    if vartype(oOutLookObject) != "O"
    HTH

    Grüße Alexander

    Ich bekomme immer als vartype ein "O", auch wenn ich Outlook beende. Allerdings scheint es noch im Hintergrund weiter zu laufen.

    Wenn ich den Hintergrundprozess kille, dann erhalte ich zunächst:

       Element RECIPIENTS kann nicht zu einem Objekt ausgewertet werden.

    und danach, wenn ich auf ignorieren klicke:

       OLE-Fehlercode 0x80004004: Operation aborted.

    Es ist schon richtig, dass nach Createobject Outlook im Hintergrund bereits gestartet ist. Aber für den Fall, dass es überhaupt nicht auf dem entsprechenden PC installiert ist, benötige auch eine Lösung, um die Fehlermeldungen abzufangen bzw. vorher entsprechende Maßnahmen ergreifen zu können.

    Gruß Jürgen

    Noch ein Nachtrag:

    Ich habe gerade das Programm auf einem anderen PC mit laufendem Outlook laufen lassen. Dort hat es bisher immer funktioniert und jetzt erhalte ich die Meldung:

    Programmfehler!
    OLE-IDispatch-Ausnahmecode 4096 von Microsoft Office Outlook. Die
    Messaging-Programmschnittstelle hat einen unbekannten Fehler
    zurückgeliefert. Falls das Problem weiter besteht, starten Sie Outlook neu ...

    Nur nützt das leider nichts ;-((


    <--------(nur Fliegen sind schöner!)-------->




    Mittwoch, 24. Januar 2018 14:19
  • Hallo Jürgen, 
    ja die Antwort war nicht die beste.
    Versuche bitte GetObject. 
    So sollte das etwa aussehen:
     oOutLookObject = GetObject('Outlook.Application')

    Der Unterschied soll sein das GetObject nur eine Instanz erhält wenn denn Outlook auch offen ist.
    Danach sollst Du oOutlookObject abfragen können. 

    oder etwa so:

      TRY
    oOutLookObject  = getobject('',"outlook.application")
    Catch ....
    oOutLookObject = createobject("outlook.application")
    ENTRY

    Grüße Alexander

    Mittwoch, 24. Januar 2018 15:56
  • 1. Wenn Outlook gar nicht installiert ist, haut Dir CREATEOBJECT("Outlook.Application") ein Fehler 1733 um die Ohren, und zwar sofort. Wenn das auf einem Rechner ohne Outlook immer noch ein Objekt liefert, dann ist da was halb installiert oder halb deinstalliert. Dagegen hast Du kein Mittel, Du musst Dich auf sorgfältig verwaltete Rechner verlassen können.

    Aber natürlich kannst Du das CREATEOBJECT in TRY..CATCH machen, um den Fehler lokal abzufangen und im CATCH Bereich dann zu melden, dass Outlook nicht (sauber) installiert ist. Dito bei CREATEITEM und anderen Aufrufen, die bei sauberer Installation auch sauber funktionieren sollten.

    2. Der Recipients Fehler deutet darauf hin, dass die mitglieder.email Deinem Outlook nicht bekannt ist. Wenn ein Recipient per Recipients.Add() gesetzt wird gibt es tyischerweise einen automatischen Check mit dem Outlook Addressbuch o.ä. Wie wäre es mit ALLTRIM(mitglieder.email)? Schon alleine Leerzeichen nach dem Ende der eigentlichen Mailaddresse mögen stören, dito führende Leerzeichen.

    Nebenbei: Weswegen ich "o.ä." sagte. Wenn Outlook einmal eine Mailadresse verwendet hat, wird sie deswegen noch lange nicht in das Addressbuch eingetragen, ist aber dem Prüfmechanismus von Recipients.Add() bekannt. Irgendwo speichert Outlook da ein Systemaddressbuch o.ä.

    Einfacher ist, es oMailItem.To=ALLTRIM(mitglieder.email) zu setzen, das löst den Prüfmechanismus nicht aus. Zustellprobleme wirst Du dann mit Rückmeldungen bekommen, aber Outlook ist da raus und wirft auch diese Art von Fehler dann nicht mehr. Das Auffinden im (System)Addressbuch ist sowieso immer noch keine Garantie, eine Mailadresse kann ja jederzeit gekündigt werden und damit ungültig werden.

    3. Wenn man ein laufendes Outlook per GETOBJECT() holt und das vom Anwender gerade in einem modalen Status ist, kann Automation auch fehlschlagen, deswegen würde ich sowieso raten bei CREATEOBJECT zu bleiben. Zu NT und anfangs XP Zeiten war jeder neue Prozess immer noch eine Bürde, die u.U. auch mit zuwenig RAM ein System instabil machte, wenn man dann noch einen Prozess startete. Aber da sind wir durch.

    Mit Fehlern, die Du von unsauberen PCs hast kann man Dir nicht mit VFP Code helfen, da musst Du dann ran und neu installieren. Office365 kann seins dazu tun, wenn Outlook gar nicht als echte Desktop Anwendung installiert ist kann Outlook auch nicht so automatisiert werden.

    Nachtrag: Ich habe noch nie eine Click-To-Run Installation unter den Fittichen gehabt, bei denen Anwendungen gestreamt werden. Die Beobachtung, Office Anwendungen seien nur während sie laufen automatisierbar könnten damit zusammenhängen, wenn nur während ihres Laufs auch die entsprechende EXE als temporäre Installation vorliegt und auch nur dann für OLE Automation verfügbar ist. Was CREATEOBJECT() dann genau macht und warum es nicht sofort scheitert, wenn Outlook nicht gerade läuft kann ich nur raten. Was ich finde ist, dass Click-To-Run Installationen Typelib Informationen nicht in den HKEY_CLASSES_ROOT Zweig der Registry schreiben, sondern nur in HKEY_LOCAL_NACHINE. Das alleine würde aber einfach nur ein Scheitern des CREATEOBJECT bewirken.

    Tschüß, Olaf.


    Olaf Doschke - http://www.doschke.name

    Donnerstag, 25. Januar 2018 10:21
  • Danke für Eure Hilfen, aber ich mache es mir erst einmal einfach: Ich schreibe auf die Startseite, wenn die oder die Fehlernummer auftritt, dann soll der Anwender prüfen, ob Outlook läuft ;-))

    Ich habe noch mehr "Baustellen", wichtigere. Wenn das alles erledigt ist, widme ich mich diesem Problem, noch einmal.

    Bis dahin muss das so reichen. Denn bei einem intakten System mit Outlook tritt der Fehler schließlich nicht auf.

    Nochmals danke und Grüße

    Jürgen


    <--------(nur Fliegen sind schöner!)-------->

    Mittwoch, 31. Januar 2018 16:14