June, 2010 - Office Development is more than VBA - Site Home - MSDN Blogs
Blog - Title

June, 2010

  • Office Development is more than VBA

    Die Neuigkeiten von VSTO 2010 vorgestellt

    • 0 Comments

    Gerade ist ein Online-Artikel von mir erschienen, indem die Möglichkeiten von Visual Studio 2010 angerissen werden, Office-Lösungen zu erstellen. Der Artikel soll einen Überblick über die Neuigkeiten von VS2010 in Bezug auf Office 2010 bieten und beschäftigt sich nicht mit solch “alten” Technologien wie Task Panes oder Custom Forms Regions (die es natürlich immer noch gibt). Er ist als Ergänzung zu den bekannten Technologien zu sehen.

    Weitere Informationen gibt es dann in der Ausgabe 09 des dotNet Magazins (ab 4. August am Kiosk), u.a. auch ein Artikel zum Security und Deployment Modell von VSTO 2010.

  • Office Development is more than VBA

    Open XML Package Editor für VS2010

    • 0 Comments

    Für Visual Studio 2008 gab es die ein Plug-In, welches das Öffnen und Bearbeiten von Open XML Dateien erlaubte. Enthalten war es in der VSTO Power Tools. Leider arbeitete das nicht mit VS2010 zusammen. Jetzt gibt es dafür Abhilfe. Der Open XML Package Editor Power Tool for Visual Studio 2010 bringt die Funktionalität zurück in Visual Studio 2010 und kann aus der Visual Studio Gallery geladen werden.

    Damit können Open XML- und XPS-Dateien geöffnet und die einzelnen Parts eingesehen, entfernt und geändert sowie neue Parts hinzugefügt werden.

    Besonders hilfreich ist, dass das Tool erkennt, wenn die geöffnete Datei extern verändert wurde und das Laden der Änderungen anbietet, ohne die datei vorher schließen zu müssen.

    OXPE1

    Ein Doppelklick auf einen Part führt zum Öffnen desselben in Visual Studio’s XML Editor:

    OXPE2

  • Office Development is more than VBA

    Outlook Ribbon XML – 150 Zeilen Code eingespart

    • 0 Comments

    Ich hatte mir vor einigen Jahren ein AddIn für Outlook 2003 gebastelt, welches mir ausgewählte Kontakte verarbeitet und Adressaufkleber druckt. Über die Jahre hinweg habe ich es nach Office 2007, von VB.NET nach C# und von VSTO 2005 SE nach VSTO 3.0 portiert. Nun bringt Outlook 2010 das Ribbon UI für den Explorer. Mein Add-In lief immer noch, jetzt im Add-Ins Tab integriert, sah aber natürlich unschön aus.

    Also habe ich mich heute an die Arbeit gemacht, eine korrekte Integration in das Ribbon-Modell von Office 2010 zu bauen.

    Das RibbonX für die Gruppe war schnell gebaut:

    ---------------------------------------------------------------------------------

    <ribbon>
      <tabs>
        <tab idMso="TabContacts">
          <group id="groupCM" label="Contact Manager"
                 insertAfterMso="GroupViewGallery">
            <button id="btnCreateLabels" label="Create Labels"…
                    onAction="onCreateLabels"/>
            <button id="btnSendMails" label="Send Email" …
                    onAction="onSendMail"/>
            <button id="btnCheckAddresses" label="Validate Address" …
                    onAction="onCheckAddress"/>
          </group>
        </tab>
      </tabs>
    </ribbon>

    ---------------------------------------------------------------------------------

    Dank Integration in den TabContacts fiel gleich die Prüfung weg, ob sich der Benutzer in den Kontakten aufhält und natürlich auch der (reichlich unlesbarer) Code zum Erzeugen der Menüeinträge:

    ---------------------------------------------------------------------------------

    Office.CommandBar menuBar = olEx.CommandBars["Menu Bar"];
    ContactManager =
       (Office.CommandBarPopup)menuBar.Controls.Add
          (Office.MsoControlType.msoControlPopup, 1,
           null, menuBar.Controls.Count, true);
    ContactManager.Caption = "Contact Manager";
    ContactManager.Visible = false;

    mnuLabelMaker =
       (Office.CommandBarButton)ContactManager.Controls.Add
          (Office.MsoControlType.msoControlButton, 1,
           null, 1, true);
    mnuLabelMaker.Caption = "Create Labels";
    mnuLabelMaker.Tag = "_Labels";
    mnuLabelMaker.Click +=
       new Microsoft.Office.Core.
         _CommandBarButtonEvents_ClickEventHandler(LabelClickHandler);
    mnuLabelMaker.Visible = true;

    ---------------------------------------------------------------------------------

    Adé, lieber Code, wir brauchen Dich nicht mehr.

    Allerdings versuchte Outlook nun auch, denselben Ribbon-Eintrag beim Öffnen eines einzelnen Kontakts anzuzeigen, was natürlich fehl schlug:

    image

    Ja, da war doch noch etwas: An der Stelle, wo das Ribbon XML geladen wird, kann man einschränken (IRibbonExtensibility Members):

    ---------------------------------------------------------------------------------

    public string GetCustomUI(string ribbonID)
    {
      if (ribbonID == "Microsoft.Outlook.Explorer")
        return GetResourceText("ContactManager.MainRibbon.xml");
      else
        return string.Empty;

    }

    ---------------------------------------------------------------------------------

    Wo bekommt man nun die ribbonID her?

    Der Ribbon Designer hat eine Property RibbonType, wo man alle Typen aufgelistet bekommt:

    RibbonTypes

    Die Ribbon Callbacks sind wieder einfach:

    ---------------------------------------------------------------------------------

    public void onCreateLabels(Office.IRibbonControl control)
    {
         Globals.ThisAddIn.CreateLabelsFromRibbon();
    }

    ---------------------------------------------------------------------------------

    Jetzt noch schnell die Kontextmenüeinträge bauen und fertig ist der Laden. … Ganz so schnell ging es dann doch nicht. Welches Kontextmenü ist das richtige und wie heißt es?

    Die Namen und IDs der Menüs und Befehle sind hier zu finden (mehrere einzelne Excel-Files). Die Datei für den Outlook Explorer öffnen und die Spalte Tab nach “None (Context Menu)” fiiltern. Danach kann man in der Spalte daneben die Namen der Kontextmenüs finden (Duplikate entfernen):

    ContextMenuAttachments ContextMenuNoteSystemMenu
    ContextMenuCalendarItem ContextMenuQuickFlags
    ContextMenuCalendarView ContextMenuRemoteDocument
    ContextMenuCalendarViewFreeBusyBar ContextMenuSearchRoot
    ContextMenuCalendarViewTimeBar ContextMenuShortcut
    ContextMenuCardView ContextMenuStore
    ContextMenuCategories ContextMenuTableArrangeBy
    ContextMenuContactItem ContextMenuTableView
    ContextMenuContactsMoreActions ContextMenuTableViewColumn
    ContextMenuFlaggedContactItem ContextMenuTaskItem
    ContextMenuFlaggedMailItem ContextMenuTimelineView
    ContextMenuFolder Group/Context Menu Name
    ContextMenuGroupHeader MenuCalendarNewItem
    ContextMenuIconView MenuContactsNewItem
    ContextMenuJournalItem MenuJournalNewItem
    ContextMenuMailItem MenuMailNewItem
    ContextMenuMailMoreActions MenuNotesNewItem
    ContextMenuMultipleItems MenuTasksNewItem
    ContextMenuNoteItem

     

    Das Kontextmenü für einen einzelnen Kontakt war schnell gefunden: ContextMenuContactItem. Allerdings stellte sich heraus, dass bei mehreren ausgewählten Kontakten wieder ein anderes angezeigt wurde. Mit ein bisschen Suchen kam ich auf ContextMenuMultipleItems. (Die Doku dazu könnte ein wenig hilfreicher sein) Das RibbonX dafür sieht dann so aus:

    ---------------------------------------------------------------------------------

    <contextMenus>
      <contextMenu idMso="ContextMenuContactItem"> 
        <button id="ctxCreateLabels" label="Create Labels" …
                onAction="onCreateLabels" insertAfterMso="Copy"/>
      </contextMenu>
      <contextMenu idMso="ContextMenuMultipleItems">
        <button id="ctxCreateLabelsMI" label="Create Labels" … 
                onAction="onCreateLabels" insertAfterMso="Copy"/>
      </contextMenu>
    </contextMenus>

    ---------------------------------------------------------------------------------

    Die Vorgängerversion bediente sich noch des Outlook-Objektmodells und sah (auszugsweise) so aus:

    ---------------------------------------------------------------------------------

    olEx.Application.ItemContextMenuDisplay +=
       new Microsoft.Office.Interop.Outlook
           .ApplicationEvents_11_ItemContextMenuDisplayEventHandler
           (Application_ItemContextMenuDisplay);

    void Application_ItemContextMenuDisplay(
               Microsoft.Office.Core.CommandBar CommandBar,
               Microsoft.Office.Interop.Outlook.Selection Selection)

    {
       if (ContactView)
      {
        mnuCtxLabelMaker =
           CommandBar.Controls.Add(
              Office.MsoControlType.msoControlButton, 
              missing,
              missing,
              missing,
              true) as Office.CommandBarButton;
        mnuCtxLabelMaker.BeginGroup = true;
        mnuCtxLabelMaker.Caption = "Create Labels";
       
    mnuCtxLabelMaker.Tag = "Create_Labels";
        mnuCtxLabelMaker.FaceId = 65;

        mnuCtxLabelMaker.Click += new Microsoft.Office.Core.
          _CommandBarButtonEvents_ClickEventHandler(LabelClickHandler);
        mnuCtxLabelMaker.Visible = true; 
        …
      }
      …
    }

    ---------------------------------------------------------------------------------

    Nicht sonderlich schön. Besonders, wenn man das schon etwas kryptische Event-Prinzip von Outlook betrachtet. Da faßt sich doch Ribbon XML viel besser an.

     

    Das Endergebnis ist nun folgendes:

     

    1. Ribbon-Integration im Outlook Explorer:

    image

    2. Ribbon-Integration in das Kontextmenü für einen einzelnen Kontakt:

    Snip2

    2. Ribbon-Integration in das Kontextmenü für mehrere ausgewählte Kontakte:

    Snip1

    Alles in allem habe ich etwa 150 Zeilen alten Code eingespart, wofür ich vielleicht ein Fünftel davon in neuen Code (RibbonX und Callbacks) investiert habe.

     

    siehe auch: Show and Hide Context Menu Items in Outlook 2010

  • Office Development is more than VBA

    VSTO 2010: Multi Target Deployment

    • 0 Comments

    Bisher wurde je ein Projekt in ein ClickOnce Package gepackt. Bei mehreren Add-Ins, vielleicht auch noch für verschiedene Anwendungen, wird es schnell unübersichtlich. Jedes Paket muss einzeln getestet werden. Das ändert sich mit VSTO 2010. Nun können mehrere Add-Ins zu einem Paket zusammengefasst werden. Ich will hier einmal beschreiben, welche Schritte dazu nötig sind.

    Nehmen wir an, wir haben 2 Lösungen (Excel und Word), die gemeinsam verteilt werden sollen. Zunächst wird ein weiteres Projekt der Solution hinzugefügt (ContosoInstaller), welches die Basis für das gemeinsame Verteilungsprojekt bildet. Das dient nur als Dummy und sollte ein Add-In-Projekt für einen Office Client sein, für den sowieso schon ein Add-In verteilt werden soll (hier Word oder Excel). Benötigt werden nur das Application Manifest (*.manifest) und das Deployment Manifest (*.vsto). Für dieses Projekt wird nun ClickOnce Deployment konfiguriert, also Pre-Requisites, Updateverhalten, Versionierung und die Starteinträge eingestellt.

    clip_image002

    Für die Einzelprojekte muss noch das Ladeverhalten des Add-Ins festgelegt werden (Publish Options: Beim Start, OnDemand, etc.).

    clip_image004

    Zu Guter Letzt wird das Publishing aller 3 Projekte durchgeführt.

    Nun ist Handarbeit angesagt, denn aus den Application Manifests der beiden Add-In-Projekte müssen Einträge in das Dummy-Manifest kopiert werden, welches damit zum Multi-Add-In-Manifest wird. Wir legen dazu einen neuen Ordner (ContosoInstaller) an, in den folgende Dateien kopiert werden:

    • ContosoInstaller\ContosoInstaller.vsto
    • ContosoInstaller\Application Files\ContosoInstaller_1_0_0_0: Alle Dateien mit dem Suffix .deploy sowie ContosoInstaller.dll.manifest.

    Die Ordnerstruktur lassen wir so, wie vom Dummy-Projekt (Publish-Ordner) vorgegeben, sonst müssen noch die Pfade innerhalb der Manifeste geändert werden. Angepasst werden muss u.U. auch die Versionsnummer, welche aber auch über das Dummy-Projekts innerhalb von Visual Studio vor dem Publishing angepasst werden kann.

    Alle 3 Application Manifeste werden in nun Visual Studio geöffnet. Aus dem Multi-Add-In-Manifest werden folgende Einträge entfernt:

    • Alle Dependency Einträge, bei denen dependencyType=“install“ ist
    • Alle vstav3:entryPoints (sollte nur einer sein)
    • Alle vstov4:customizations (sollte nur einer sein)

    Jetzt geht’s ans Kopieren. Aus beiden Application Manifests werden diejenigen Abhängigkeiten kopiert, deren Typ „Install“ ist.

    image

    Sie werden am Ende der Dependency Liste Eingefügt, wobei auf Duplikate geachtet werden muss.

    Nun werden die Entry Points kopiert (einer pro Projekt). Zu finden sind sie unter vstav3:entryPointsCollection. Sie werden an der gleichen Stelle im Zielmanifest eingefügt. Da es nun aber mehr als einen gibt, muss eine eindeutige ID vergeben werden.

    image

    Am Ende der Kopiererei müssen die Assemblies noch dem VSTO.V4 Namensraum zugeordnet werden. Das geschieht im Abschnitt vstov4:customizations. Auch hier besteht wieder die Notwendigkeit, eine ID zu vergeben.

    image

    An Ende müssen die Manifeste noch signiert werden. Dazu wird Mage.exe, das Manifest Generation Tool, benötigt, welches im Windows 7 SDK enthalten ist.

    image

    Und das Deployment Manifest wird so signiert:

    image

    (Die drei Punkte im Pfad müssen natürlich durch den korrekten Pfad ersetzt werden.)

    Damit ist das ClickOnce Package komplett fertig modifiziert und kann getestet werden.

  • Office Development is more than VBA

    Missing Developer Tab

    • 0 Comments

    Umsteiger von Office 2007 auf 2010 werden u.U. die Möglichkeit suchen, den developer Tab einzuschalten. Bei 2007 noch unter dem Stichwort “Show Developer Tab in Ribbon” zu finden, findet sich das Ganze in 2010 unter “Customize Ribbon” wieder.

    Show Dev Tab

  • Office Development is more than VBA

    Neue WebCasts zu VSTO / Office 2010 Integration mit VS2010 verfügbar

    • 0 Comments

    Wenn man mit einem Achillessehnenriss zuhause sitzt, kann man nicht wirklich viel machen. Jedenfalls nichts, was mit viel Bewegung zu tun hat. Also habe ich mir Visual Studio und Office (Jeweils 2010) hergenommen und die neuen Möglichkeiten herausgearbeitet. Herausgekommen sind 3 WebCasts:

    1. Ribbon- und Backstage-Programmierung mit Visual Studio 2010 und Office 2010
      User Interface Integration in Office 2010 mit C# 4.0
    2. Deployment von Office 2010 Erweiterungen
      Part I: Grundlagen der Anwendungsverteilung
    3. Deployment von Office 2010 Erweiterungen
      Part II: Erweiterte Möglichkeiten der Anwendungsverteilung

    Inzwischen ist die Sehne wieder halbwegs ganz und vielleicht sieht man sich ja auf dem Office Community Day nächste Woche.

  • Office Development is more than VBA

    Neues aus der Office-Welt

    • 0 Comments

    Am 14. (Karlsruhe) 15. (Düsseldorf/Neuss)  und 23. (München) Juni findet der TechDay Spezial zum Thema “Von der Schreibmaschine zur Integrationsplattform” statt. Unter anderem mit Live Demos meiner Kollegen Daniel Melanchthon und Steffen Krause.

     

    Lust auf noch mehr SharePoint? Dann melden Sie sich zur ShareConf (22.-24. Juni) an. Sie erwarten interessante Vorträge bzw. Workshops (22.6.) zu SharePoint 2010, u.a. mit unserem MTC Architekten Sven Maier.

     

    Office 2010 hat nun seine eigene neue Webseite.

    Off2010

     

    Für den Office Community Day am 17. Juni in München/Unterschleißheim gibt es noch ein paar Freie Plätze. Es geht hier um die Entwicklung von Office Business Anwendungen mit VSTO, Open XML und SharePoint.

Page 1 of 1 (7 items)