Fragensteller
BestPractise für Handling mit Outlook bei verschiedenen Office Versionen

Frage
-
Hallo liebe Community,
ich belästige euch mal wieder mit einer Frage. Durchs Googeln habe ich zwar zig Möglichkeiten, aber nicht wirklich eine Antwort auf meine Frage gefunden.
Ich möchte eine Anwendung schreiben, die eine E-Mail über Outlook automatisiert verschickt. Dazu habe ich einen Verweis auf die .NET Assembly Microsoft.Office.Interop.Outlook (Version 12.0.0.0) gesetzt. Mit dieser ist es sehr einfach, alles was ich benötige umzusetzen.
Jetzt ist jedoch das Problem, dass die Benutzer alle möglichen Versionen von Office nutzen können, von Office XP bis Office 2010. Ich weiß nicht, wie man am besten mit umgeht. Reicht es aus, wenn ich diese Microsoft.Office.Interop.Outlook.dll immer in der neuesten Version (derzeit 14.0.0.0) im selben Verzeichnis habe, wie meine Assembly oder muss ich immer was installieren? Ist es Abwärtskompatibel bis OfficeXP?
Alternativ könnte ich natürlich auch einen Verweis auf die COM Bibliothek "Microsoft Outlook 12.0 Object Library" setzen, dort auf nicht ganz so elegante Weise meine Funktionalität coden und dann den Verweis wieder entfernen und per Late Binding mein Outlook Objekt erstellen. Doch gehe ich davon aus, dass diese altertümliche Methodik zu Zeiten von .Net nicht mehr verwendet wird, oder irre ich mich? Zudem würde ich gerne wissen, warum ich diese COM Bibliothek in Visual Studio 2008 angezeigt bekomme, aber nicht in Visual Studio 2010. Ist für mich ja schon wieder ein Zeichen dafür, dass meine Vermutung stimmt, dass man lieber .Net Komponenten verwenden sollte.
Ich bin wie immer für jede Antwort sehr dankbar und schaue mir wirklich jede Antwort intensiv durch und folge sämtliche Links.
Grüße
Manuel
Alle Antworten
-
Hallo Manuel,
mein Ansatz, damit am besten umzugehen sind Dynamics. Diese gibt es seit .NET Framework 4 und sie erlauben dir einen besseren Umgang mit Late Binding. Für deinen Anwendungsfall könnte ich mir dabei etwas in dieser Art vorstellen:
dynamic outlookApp = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")); dynamic mailItem = outlookApp.CreateItem(0); // 0 = olMailItem mailItem.To = "receipient@email.de"; mailItem.Body = "Text"; mailItem.Subject = "Subject"; mailItem.Display();
Outlook registriert sich immer mit dem Namen Outlook.Application.<Versionsnummer> und zusätzlich gibt es einen Alias Outlook.Application, der auf die aktuelle Outlook-Version verweist. Damit musst du keine Outlook-Assembly referenzieren und auch keine Outlook-Assembly ausliefern.
Nun zu deiner anderen Frage: Ich glaube nicht, dass man einfach eine Outlook 14 Assembly ausliefern kann und diese funktioniert dann mit einer beliebigen anderen installierten Outlook-Version.
Viele Grüße
Martin
-
Hallo Manuel,
Reicht es aus, wenn ich diese Microsoft.Office.Interop.Outlook.dll immer in der neuesten Version (derzeit 14.0.0.0) im selben Verzeichnis habe, wie meine Assembly oder muss ich immer was installieren? Ist es Abwärtskompatibel bis OfficeXP?
Microsoft gibt keine Garantien dafür, dass die Primary Interop Assemblies rückwärtskompatibel sind. Die gemanagten Office Add-Ins müssen, zumindest in der Theorie, immer die für die jeweilige Office-Version gültigen Primary Interop Assemblies verwenden (das ist vor allem für den Office XP-Support wichtig). Eine weitere Einschränkung: Man kann Visual Studio 2010 standardmäßig nicht dazu verwenden, um VSTO-Lösungen für Office 2003 zu programmieren, da muss man immer noch Visual Studio 2008 nehmen.
Meine Empfehlung
Sollen die Add-Ins [bzw. Deine Anwendung] z.B. Office ab Version 2003 unterstützen, sollte man immer auf einem Rechner mit installiertem Office 2003, bzw. gegen Office 2003 PIAs programmieren/kompilieren und dabei Visual Studio 2008 verwenden. So vermeidet man ungewollte Inklusion von nichtunterstützten Features (bzw. automatische Referenzierung der neuesten GAC-PIAs). Für das Deployment wichtig: Ab Office 2007 werden PIAs und Policy-Dateien automatisch mitinstalliert. Hat Dein Kunde dann z.B. nicht Office 2003 sondern Office 2007 oder Office 2010 installiert, wird das Binding automatisch zur neueren PIA-Version umgeleitet ([abschaltbare] Vorwärtskompatibilität über Publisher Policy-Dateien).Mußt Du denn unbedingt Office XP-Unterstützung anbieten? Microsoft hat den Mainstream-Support bereits 2006 eingestellt und der extended Support läuft 2011 aus (Microsoft Support Lifecycle).
Informationen zum Entwerfen von Office-add-ins mithilfe von .NET Framework:
http://support.microsoft.com/kb/840585/deErstellen von Lösungen für unterschiedliche Versionen von Microsoft Office
http://msdn.microsoft.com/de-de/library/bb772080.aspxVS 2010: Verfügbare Funktionen nach Office-Anwendung und Projekttyp:
http://msdn.microsoft.com/de-de/library/aa942839.aspx
VS 2008: Verfügbare Features nach Anwendung und Projekttyp:
http://msdn.microsoft.com/de-de/library/aa942839(v=VS.90).aspxVA 2005: Verfügbare Features nach Produktkombination:
http://msdn.microsoft.com/de-de/library/aa942839(v=VS.80).aspxWhy is VS development not supported with multiple versions of Office?
http://blogs.msdn.com/b/andreww/archive/2007/06/08/why-is-vs-development-not-supported-with-multiple-versions-of-office.aspx
Nachtrag: Mit dem .NET Framework 4.0 ist nun auch die Möglichkeit vorhanden, Typinformationen aus Microsoft Office-Assemblys (PIAs) einzubetten. Für einfache Szenarien, kann man so seine Office-Anwendung beim Kunden ohne PIAs separat installieren (der effektiv von der Anwendung verwendete PIA-Code wird in der Assembly eingebettet).s.a. Exemplarische Vorgehensweise: Einbetten von Typinformationen aus Microsoft Office-Assemblys (C# und Visual Basic):
http://msdn.microsoft.com/de-de/library/ee317478.aspxGruß
Marcel- Bearbeitet Marcel RomaModerator Samstag, 6. November 2010 20:04
-
Ich kann leider kein .net 4.0 verwenden, da das Projekt weiterhin auf 3.5 bestehen bleiben soll. Danke dennoch für den Hinweis.
Diese Lösung wäre also für mich wohl die einzige noch verbliebene Möglichkeit, auch wenn der Quellcode dadurch nahezu unlesbar werden würde.
-
Ich werde es in der Firma mal ansprechen, ob OfficeXP überhaupt noch Verwendung findet bei den Kunden. Gehen wir mal davon aus, wir setzen die Mindestanforderung wirklich auf Office2003.
Wenn ich dich da richtig verstanden habe, müsste ich für Kunden mit Office2003 die PIAs im Setup mit installieren und ab Version 2007 wäre das gar nicht mehr nötig, da jede Office Installation die Dateien schon hätte. Ich könnte also gegen die 2003 PIAs coden, in meinem Projekt einen Verweis auf die Microsoft.Office.Interop.Outlook Assembly (Version 11 für Office2003) setzen und alle wären glücklich, da wenn der Kunde Office 2007 verwenden würde, die Verweise automatisch hin gebogen werden würden, richtig?
Irgendwie ist mir das aber noch immer ein zu großes Hick Hack. Wäre diese Lösung dann nicht sinnvoller, da man da komplett unabhängig wäre? Da wir noch c# 3.5 verwenden kann ich die hier bereits erwähnte Lösung mit Dynamics leider nicht verwenden.
-
Hallo Manuel
vorab zur Sicherheit: schreibst du eine eigene App, oder ein Office-Addin?
Falls App:
wenn 4.0 (mit noPIA) nicht geht, muss man noch lange nicht auf riskantes Reflection ausweichen.
Im Prinzip könnte man auch:
A) entweder nur gegen die tiefste Version kompilieren (hab ich nicht geprüft für Outlook; erfordert wohl entsprechende, alte Office-Version/PIAs auf Entwickler-PC und Vorsicht mit PIA-Referenzen/Versionen);
B) oder in separaten Projekten (Assemblies) für jede gewünschte Office-Version gegen deren PIAs eigens kompilieren und 'passende' auf Kundenrechner installieren.
B hätte den Vorteil, dass man bei Bedarf auch Features von neueren Office-Versionen sofort nutzen könnte, aber sonst Mehraufwand im Handling/Deployment. -
Vergessen zu erwähnen,... ich code eine eigene App bzw Assembly und kein Add-in für Outlook.
Wie meinst du das mit "nur gegen die tiefste Version kompilieren"? Ich könnte die PIA in der Version 11 (für Office 2003) verwenden (wobei das auch nicht mehr so sicher ist, da ich gelesen habe, dass man dafür VS2008 benötigt, wir aber VS2010 verwenden) verwenden und meinen Code dafür schreiben. Doch muss ich doch im Projekt einen Verweis auf die alte PIA setzen. Wie mache ich es dann, wenn der Kunde statt Office 2003 z.B. Office 2010 nutzt?
-
Hallo Manuel,
Wenn ich dich da richtig verstanden habe, müsste ich für Kunden mit Office2003 die PIAs im Setup mit installieren und ab Version 2007 wäre das gar nicht mehr nötig, da jede Office Installation die Dateien schon hätte. Ich könnte also gegen die 2003 PIAs coden, in meinem Projekt einen Verweis auf die Microsoft.Office.Interop.Outlook Assembly (Version 11 für Office2003) setzen und alle wären glücklich, da wenn der Kunde Office 2007 verwenden würde, die Verweise automatisch hin gebogen werden würden, richtig?
Kunden mit Office 2003: Es kann sein, dass die Office 2003 PIAs bereits installiert sind. Das müßtest Du bei der Installation überprüfen, bzw. die Office 2003 PIAs genauso wie VSTO 2.0 als Installationsvoraussetzung setzen.Kunden mit Office 2007: Hier kannst Du davon ausgehen, dass die Office 2003 PIAs bereits im GAC installiert sind. Die Bindung an die Interop Assemblies wird autom. auf die neueste Version umgeleitet.
Zur VSTO-Kompatibilität s.a.: Visual Studio Tools for Office versioning and compatibility
http://blogs.msdn.com/b/rcook/archive/2009/02/24/visual-studio-tools-for-office-versioning-and-compatibility.aspxIrgendwie ist mir das aber noch immer ein so großes Hick Hack. Wäre diese Lösung dann nicht sinnvoller, da man da komplett unabhängig wäre?
Für einfache Aufgaben, kann man natürlich late binding, bzw. Reflection verwenden. Nur sollte man dabei nicht vergessen, dass man sich genausoviele Probleme einhandelt wie man löst. Deshalb bleibe ich bei meiner Empfehlung. Es gibt zwar diverse Dritthersteller, die in gewissem Umfang Versionsunabhängigkeit zusichern, getestet habe ich diese Produkte aber nicht (keine Gewähr).
Gruß
Marcel -
Hallo Marcel,
Kunden mit Office 2003: Es kann sein, dass die Office 2003 PIAs bereits installiert sind. Das müßtest Du bei der Installation überprüfen, bzw. die Office 2003 PIAs genauso wie VSTO 2.0 als Installationsvoraussetzung setzen.
Manuel möchte kein Add-In erstellen und VSTO wird nicht benötigt, wenn man Office lediglich via Automatisierung nutzen möchte.
Thorsten Dörfler
Microsoft MVP Visual Basic
vb-faq.de -
Hallo Thorsten,
Manuel möchte kein Add-In erstellen und VSTO wird nicht benötigt, wenn man Office lediglich via Automatisierung nutzen möchte.
Manuels Posting ("Vergessen zu erwähnen,... ich code eine eigene App bzw Assembly und kein Add-in für Outlook.") und mein letztes Posting sind fast simultan veröffentlicht worden (4 Minuten Abstand), so dass ich keine Möglichkeit hatte, Manuels Erklärung zu lesen. Natürlich braucht man VSTO hauptsächlich wenn man Add-ins entwickelt.
@Manuel: Wenn Du keine Add-Ins entwickelst (wovon ich ausgegangen war), schau bitte über die entspr. Passagen hinweg. Alle weiteren Empfehlungen gelten nach wie vor.
Gruß
Marcel -
Manuel,
ich denke auch mit VS2010 plus 3.5 als Zielframework klappt dies für 'normale' Office-Automation per:
lies unten insbesondere den Abschnitt "Bindung der Assemblyumleitung"
http://msdn.microsoft.com/de-de/library/15s06t57.aspx
wobei man wohl (mind. offiziell) einen Entwickler-PC (oder eine VM) braucht, wo _nur_ die ältere Office-Version installiert ist
(zumindest kurzzeitig fürs setzen der COM-Verweise und das kompilieren).
Deine Kunden (bzw dein Setup) müssen sodann logischerweise immer die zur lokal vorhandenen Office-Version passenden PIAs prüfen/installieren (Details hinlänglich bekannt).
(IMHO Office XP ist eher zu alt) -
Für einfache Aufgaben, kann man natürlich late binding, bzw. Reflection verwenden. Nur sollte man dabei nicht vergessen, dass man sich genausoviele Probleme einhandelt wie man löst. Deshalb bleibe ich bei meiner Empfehlung.
Mit was für Problemen kann bzw. müsste ich rechnen? Es geht hier nur um einfache Dinge wie E-Mail verschicken (Empfänger, Betreff, HTML Body, Signatur, Anhang), Termin erstellen und Aufgabe erstellen. Mehr möchte ich nicht machen. -
Hallo Manuel,
Mit was für Problemen kann bzw. müsste ich rechnen?
Einige Nachteile, die mir gerade einfallen (in keiner bestimmten Reihenfolge):
- späte Bindung ist etwas umständlicher (erzeugt Spaghetticode)
- späte Bindung wird nicht durch IntelliSense unterstützt
- späte Bindung ermöglicht es dem Compiler nicht, Typ- und Syntaxprüfungen vorzunehmen
- späte Bindung ist nicht so performant wie frühe Bindung (frühe Bindung ist doppelt so schnell)
- späte Bindung ist zu offen (wie wird wohl Office 2012 implementiert werden? wird es mir dieselben BindingFlags erlauben? was wird es alles noch tun wenn ich eine neue Aufgabe anlege? wird GUI-Interaktion notwendig sein? welche Sicherheitsfeatures werden mit-getriggert? )
- späte Bindung ist nicht wartungsfreundlich (schon mal versucht, an ein Ereignis über late binding zu binden?)
Wenn Du das alles in Kauf nehmen kannst, ist late binding ein mögliches Szenario. Siehe dazu auch die MSDN-Dokumentation weiter unten.Bindung von Office-Automatisierungsservern mit Visual C# .NET:
http://support.microsoft.com/kb/302902/de-deVerwendung der frühen und späten Bindung in der Automatisierung:
http://support.microsoft.com/kb/245115/DE/
Gruß
Marcel -
Ok, danke für die Info. (an Alle)
Eine Frage habe ich noch. Wenn wir hier von PIAs reden, von was sprechen wir da? Ich kann ja über "Verweise hinzufügen" und dann auf den Register ".NET" ein Verweis auf Microsoft.Office.Interop.Outlook 14.0 setzen und ich kann im Register "COM" (zumindest in VS2008) ein Verweis auf sowas setzen. Ist es das selbe oder unterscheiden die sich doch? Die Pfade der Verweise sind definitiv unterschiedlich. Im ersteren Fall befindet sich die DLL im Visual Studio Verzeichnis und im letzteren Fall im Office Verzeichnis.
-
Hallo Manuel,
Eine Frage habe ich noch. Wenn wir hier von PIAs reden, von was sprechen wir da?
PIA steht für Primary Interop Assembly. Aus dem MSDN:
"Eine COM-Typbibliothek, die als eine Assembly importiert und nicht vom Herausgeber der ursprünglichen Typbibliothek, sondern von einer anderen Person signiert wurde, kann nicht als primäre Interop-Assembly verwendet werden.Nur der Herausgeber einer Typbibliothek kann eine primäre Interop-Assembly erstellen, die als Einheit die offiziellen Typdefinitionen für die Interoperabilität mit den zugrunde liegenden COM-Typen bereitstellt."Primäre Interop-Assemblys:
http://msdn.microsoft.com/de-de/library/aax7sdch.aspx"Obwohl grundsätzlich jeder Entwickler, der COM-Typen aus einer .NET Framework-Anwendung verwenden möchte, eine Interop-Assembly generieren kann, führt dies in der realen Anwendung zu einem Problem. Immer wenn ein Entwickler eine COM-Typbibliothek importiert und signiert, wird ein Satz eindeutiger Typen erstellt, die mit den von anderen Entwicklern importierten und signierten Typen inkompatibel sind. Zur Vermeiden dieses Inkompatibilitätsproblems sollten alle Entwickler die vom Hersteller bereitgestellte und signierte primäre Interop-Assembly verwenden."
"Zusätzlich zur Bereitstellung garantierter Typkompatibilität werden primäre Interop-Assemblys vom Hersteller häufig angepasst, um die Interoperabilität zu verbessern."
Programmieren mit primären Interop-Assemblys:
http://msdn.microsoft.com/de-de/library/baxfadst.aspxGruß
Marcel -
Hallo Manuel,
leider erst jetzt, da ich momentan viel zu tun habe ...
Es ist in solchen Situationen (wie Deiner) "best practice" (was ich auch schon öfter veröffentlicht habe und vielfach erfolgreich angewandt wurde), gegen die tiefste IA zu implementieren. Das hybride Einsetzen von Latebind/EarlyBind wird auch gerne eingesetzt. Die Office-Version die dem tiefsten IA entspricht sollte dann vorteilhafter Weise auch auf dem Entwicklungsrechner sein. Kurz noch eine Beschreibung aus einem alten Posting herauskopiert:ok. IA bedeutet Interop Assembly. Das ist die Assembly, die durch die Einbindung der "Microsoft Word XX Object Library"
(über Verweise) eine "Microsoft.Office.Interop.Word.dll" erzeugt, die Du zum Beispiel über Eigenschaften auf "Lokale Kopie"=true
festlegen kannst, und so zur Verfügung hast. Ich hatte hier mal ein Beispiel für Word gemacht: [Info].
Die "tiefste zu supportende IA" ist entsprechend die Version der Interop Assembly, dessen entsprechende Office Version Deine Kunden als unterste Version haben. Also sagen wir mal Office 97 - obwohl ich mal annehme, es ist wahrscheinlich Office XP o.?..
Nun solltest Du bei der Entwicklung entweder solche latebind COM Konstrukte/Aufrufe (wie in meinem Artikel) nehmen, oder eine Mischung, die dann eben aufwärtskompatibel sind (neben anderen). Es kommen quasi höchstens Parameter hinzu, was aber eben kompatibel ist.
Und da sind wir bei der (Typ) Signatur ... das sind eben die Namen von Parametern, Typen und R?ckgabewerten, die den Typ eindeutig machen. Nur einige wenige in Vor-Versionen als deprecated gekennzeichneten Member können in der Folge-"Folge"-Version ggf. nicht mehr da sein, aber das ist sehr selten. [oder eben bei .NET 4.0 eben enorme Vereinfachungen "geniessen"). Es gibt andere Varianten der Implementierungs-Strategien für versionsunabhängiges Schreiben von managed Office-Apps.
ciao Frank -
Hallo zusammen,
wie sieht das eigentlich mit den Starter Versionen von Office 2010 aus? Ein für Word 2003 entwickeltes Projekt lief problemlos mit Word 2010. Probleme treten auf einem System auf, das kein vollwertiges Office, sondern nur die Word und Excel Starter-Versionen kennt. Die 2010er PIAs ließen sich nicht korrekt installieren (tauchen in der Liste installierter Software auf, die entsprechenden Interop Assemblies liegen aber systemweit in keiner 14er Version vor).
Gibt es hier trotzdem die Möglichkeit, einfache Funktionen (Dokument auf Basis einer Vorlage erzeugen, Text einfügen, Dokument speichern) zu nutzen?
Gruß
Anja -
Hallo Anja
es scheint da schon Einschränkungen zu geben:
http://msdn.microsoft.com/de-de/library/bb608617.aspx
"Visual Studio 2010 unterstützt nicht das Ausführen von Office-Lösungen,
wenn auf dem Endbenutzercomputer eine Version von Microsoft Office Starter 2010 installiert ist."
wobei da nicht ganz klar ist, ob dies nur VSTO oder Automation (via PIAs) generell betrifft. -
Hallo Anja,
> Starter Versionen ...
Programmierbarkeit/Automation ist bei den Starter Editionen nicht supportet / bzw. deaktiviert.
Auch ActiveX / COM im Normalfall nicht: http://support.microsoft.com/kb/980222/de
Du kannst nur (ganz grundlegende) Makros intern benutzen.
[Unterstützung der Features von Word Starter - Office Starter - Microsoft Office]
oder Workarounds über "Speichern unter" in andere Formate ausführen.
ciao Frank