Announcement

Collapse
No announcement yet.

Beenden von COM AddIn in Outlook

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

  • Beenden von COM AddIn in Outlook

    Hallo zusammen!

    Ich habe in einer EXE ein Automatisierungsobjekt angelegt. Diese EXE wird damit von Outlook 2000 aus gestartet. Mein Problem liegt nun darin, dass wenn Outlook beendet wird (mit Beenden und Abmelden) die EXE im Speicher bleibt. Deswegen habe ich die Anweisung Application.Terminate eingebaut. Nur kommt jetzt eine Meldung vom COM-Server, dass noch ein- oder mehrere Clients auf den Server zugreifen. Wie muss ich dieses AddIn beenden, damit das System sauber beendet wird? Danke!

    Martin

  • #2
    Hallo!

    In dem Zusammenhang habe ich noch ein anderes Problem. Wenn Outlook 2000 keine Verbindung zum Exchange-Server herstellen kann oder wenn Outlook abgestürzt ist, dann führt jeder Zugriff auf ein Objekt von Outlook zu einer Exception mit anschliessendem Absturz. Besteht eine Möglichkeit diese Fälle abzufangen (try-except funktioniert nicht; wäre aber auch nicht besonder schön :-)?

    Marti

    Comment


    • #3
      Hallo,

      der Weg über einen Local Server (EXE) ist leider nicht der richtige Weg. Microsoft hat für MS Office COMAddIns mit <b>IDTExtensibility2</b> ein spezielle Interfaces vordefiniert, das das eigene COM-Objekt nur implementieren muss:
      <pre>
      uses
      ComObj, ActiveX, W2KAdd1_TLB, StdVcl, AddInDesignerObjects_TLB;

      type
      TW2KAddIn1 = class(TAutoObject, IW2KAddIn1, IDTExtensibility2)
      protected
      { Protected-Deklarationen }
      procedure OnConnection(const Application: IDispatch;
      ConnectMode: ext_ConnectMode;
      const AddInInst: IDispatch;
      var custom: PSafeArray); safecall;
      procedure OnDisconnection(RemoveMode: ext_DisconnectMode;
      var custom: PSafeArray); safecall;
      procedure OnAddInsUpdate(var custom: PSafeArray); safecall;
      procedure OnStartupComplete(var custom: PSafeArray); safecall;
      procedure OnBeginShutdown(var custom: PSafeArray); safecall;
      end;
      </pre>
      Somit wird das eigene COM-Objekt von der jeweiligen Office-Anwendung über bestimmte Zustände informiert. Zum Beispiel ruft die Office-Anwendung immer dann <b>OnBeginShutdown</b> auf, wenn die Anwendung heruntergefahren wird. Das eigene Objekt hat hier die Gelegenheit, aufzuräumen.

      Um das Interface IDTExtensibility2 nutzen zu können, muss die Typbibliothek aus <b>MSADDNDR.DLL</B> importiert werden.

      Wenn der aus Outlook heraus gestarter Local Server auch nach dem Ende von Outlook weiterläuft, würde mich interessen, wie dieser Local Server in Outlook angefordert wird. Normalerweise beendet sich ein Local Server von selbst, wenn der letzte Interface-Zeiger des letzten Clients ungültig wird. Nur in begründeten Fällen würde ich hier zur API-Funktion <b>CoDisconnectObject</b> greifen, um zwangsweise alle noch bestehenden Verbindungen zu beenden.

      Warum soll try..except nicht funktioneren, wie sieht ein Aufrufbeispiel aus

      Comment


      • #4
        Hallo,

        warum ist der Weg über einen Local-Server falsch? Ich habe eine EXE erstellt mit einem Automatisierungsobjekt, welches diese IDTExtensibility2-Schnittstelle implementiert. Beim Beenden wird alles aufgeräumt, allerdings nicht über OnBeginShutdown sondern wie im Buch "Anwendungsentwicklung mit Outlook 2000" von MicrosoftPress beschrieben mittels ExplorerClose. Das deshalb weil OnBeginShutdown und OnDisconnect u. Umständen nicht aufgerufen werden (je nach Umgebung).

        Jetzt ist mein Problem, dass wenn Outlook beendet wird nicht automatisch auch die EXE beendet wird. D.h. Outlook und EXE bleiben im Speicher. Deshalb beende ich die EXE im ExplorerClose-Ereignis mit Application.Terminate. Das funktioniert zwar, allerdings kommt eben die Meldung vom COM-Server. Ist auch klar, weil ja Outlook zu diesem Zeitpunkt noch das Automatisierungsobjekt verwendet. Es muss ja doch noch einen anderen Weg geben...

        Wegen TRY-EXCEPT: das werde ich noch einmal probieren. Vielleicht habe ich da einen Aufruf übersehen (ist schon länger aus, als ich das versucht habe)...

        Danke für die rasche Antwort!

        Marti

        Comment


        • #5
          Hallo,

          in diesem Fall wird nur die Benutzeroberfläche von Outlook abgeklemmt, aber Outlook als Automation-Server bleibt im Arbeitsspeicher. Somit "lebt" der Client des eigenen Local Servers, so dass dieser nicht beendet werden "darf".

          Hinter dem <b>Explorer</b>-Objekt von Outlook verbirgt sich nur die Anzeige des Inhalts eines Ordners, aber nicht das Objekt selbst. Somit ist auch klar, warum der Interface-Zeiger auf den eigenen Local Server nicht freigegeben wird. Wenn CoDisconnectObject nicht verwendet werden soll, kann man zum folgenden Hack greifen, um diese Warnmeldung abzuwürgen:
          <pre>
          uses
          ComServ;

          type
          TComServerHack = class (TComServer);

          procedure TForm1.KillCOMServer(Sender: TObject);
          begin
          while ComServer.ObjectCount > 0 do
          TComServerHack (ComServer).CountObject(False);
          ...
          end;
          </pre&gt

          Comment


          • #6
            Hallo!

            Das stimmt so nicht ganz. In diese ExplorerClose-Routine kommt er nur mittels "Beenden und Abmelden" und nicht wenn er nur den letzten sichtbaren Explorer schliesst. Mit folgendem Code verbinde ich zu diesem Ereignis:

            FExplorerEvents := TExplorerEvents.Create(nil);<br>
            FExplorerEvents.Close := OnExplorerClose;<br>
            FExplorerEvents.Connect(AppObject.OutlookApp.GetNa mespace('MAPI').GetDefaultFolder(olFolderCalendar) .GetExplorer(EmptyParam));

            Somit wird normalerweise auch Outlook geschlossen, wenn alle erzeugten Objekte (und angeforderte Interfaces) wieder entfernt werden. In einer DLL gibt es dahingehend keine Schwierigkeiten. Nur bei einer EXE mit einem Automatisierungsobjekt gibts diese Problemchen.

            Aber diesen Hack werd ich mal ausprobieren... Schönen Dank!!

            Marti

            Comment


            • #7
              Hallo!

              Danke, funktioniert! Gibt's da irgendwelche Nachteile zu erwarten?

              Marti

              Comment


              • #8
                Hallo,

                solange die Verbindung nur von Outlook hergestellt wird, sollten keine Nebenwirkungen auftreten

                Comment

                Working...
                X