Come compilare un componente aggiuntivo COM di Office usando Visual C# .NET

Riepilogo

Microsoft Office XP, Microsoft Office 2003 e Microsoft Office 2007 supportano un'architettura di progettazione uniforme per la creazione di componenti aggiuntivi per applicazioni per migliorare e controllare le applicazioni di Office. Questi componenti aggiuntivi sono denominati componenti aggiuntivi COM (Microsoft Component Object Model). Questo articolo dettagliato illustra i componenti aggiuntivi COM di Office e descrive come compilare un componente aggiuntivo COM di Office usando Microsoft Visual C# .NET.

Interfaccia IDTExensibility2

Un componente aggiuntivo COM è un server COM in-process, o DLL (ActiveX Dynamic Link Library), che implementa l'interfaccia IDTExensibility2 come descritto nella libreria dei tipi della finestra di progettazione dei componenti aggiuntivi Microsoft (Msaddndr.dll). Tutti i componenti aggiuntivi COM ereditano da questa interfaccia e devono implementare ognuno dei relativi cinque metodi.

Onconnection

L'evento OnConnection viene generato ogni volta che il componente aggiuntivo COM è connesso. Il componente aggiuntivo può essere connesso all'avvio, dall'utente finale o tramite Automazione. Se l'evento OnConnection viene restituito correttamente, si dice che il componente aggiuntivo venga caricato. Se viene restituito un messaggio di errore, l'applicazione host rilascia immediatamente il riferimento al componente aggiuntivo e l'oggetto viene eliminato.

L'evento OnConnection accetta i quattro parametri seguenti:

  • Applicazione: riferimento all'oggetto applicazione host.

  • ConnectMode: costante che specifica la modalità di connessione del componente aggiuntivo. Il componente aggiuntivo può essere connesso nei modi seguenti:

    • ext_cm_AfterStartup: il componente aggiuntivo viene avviato dall'utente finale dalla finestra di dialogo Componenti aggiuntivi COM.
    • ext_cm_CommandLine: il componente aggiuntivo è connesso dalla riga di comando. Si noti che ciò non si applica alla creazione di componenti aggiuntivi COM per le applicazioni di Office.
    • ext_cm_External: il componente aggiuntivo è connesso da un'applicazione esterna tramite Automazione. Si noti che ciò non si applica alla creazione di componenti aggiuntivi COM per le applicazioni di Office.
    • ext_cm_Startup: il componente aggiuntivo viene avviato dall'host all'avvio dell'applicazione. Questo comportamento è controllato da un'impostazione nel Registro di sistema.
  • AddInInst: riferimento all'oggetto COMAddIn che fa riferimento a questo componente aggiuntivo nell'insieme COMAddIns per l'applicazione host.

  • Personalizzato: matrice di valori di tipo Variant che possono contenere dati definiti dall'utente.

OnDisconnection

L'evento OnDisconnection viene generato quando il componente aggiuntivo COM è disconnesso e poco prima dello scaricamento dalla memoria. Il componente aggiuntivo deve eseguire qualsiasi pulizia delle risorse in questo evento e ripristinare le modifiche apportate all'applicazione host.

L'evento OnDisconnection accetta i due parametri seguenti:

  • RemoveMode: costante che specifica la modalità di disconnessione del componente aggiuntivo. Il componente aggiuntivo può essere disconnesso nei modi seguenti:

    • ext_dm_HostShutdown: il componente aggiuntivo viene disconnesso alla chiusura dell'applicazione host.
    • ext_dm_UserClosed: il componente aggiuntivo viene disconnesso dall'utente finale o da un controller di automazione.
  • Personalizzato: matrice di valori di tipo Variant che possono contenere dati definiti dall'utente.

OnAddInsUpdate

L'evento OnAddInsUpdate viene generato quando viene modificato il set di componenti aggiuntivi COM registrati. In altre parole, ogni volta che un componente aggiuntivo COM viene installato o rimosso dall'applicazione host, questo evento viene generato.

OnStartupComplete e OnBeginShutdown

Sia il metodo OnStartupComplete che il metodo OnBeginShutdown vengono chiamati quando l'applicazione host ha lasciato o sta entrando in uno stato in cui è necessario evitare l'interazione dell'utente perché l'applicazione è occupata a caricarsi o scaricarsi dalla memoria. Il metodo OnStartupComplete viene chiamato solo se il componente aggiuntivo è stato connesso durante l'avvio e il metodo OnBeginShutdown viene chiamato solo se l'host disconnette il componente aggiuntivo durante l'arresto.

Poiché l'interfaccia utente per l'applicazione host è completamente attiva quando questi eventi vengono generati, possono essere l'unico modo per eseguire determinate azioni che altrimenti non sarebbero disponibili dall'evento OnConnection e dall'evento OnDisconnection.

Registrazione del componente aggiuntivo COM

Oltre alla normale registrazione COM, un componente aggiuntivo COM deve registrarsi a ogni applicazione di Office in cui viene eseguito. Per registrarsi con una particolare applicazione, il componente aggiuntivo deve creare una sottochiave, usando il relativo ProgID come nome per la chiave, nel percorso seguente:

HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID

Il componente aggiuntivo può fornire valori in questa posizione della chiave sia per un nome visualizzato descrittivo che per una descrizione completa. Inoltre, il componente aggiuntivo deve specificare il comportamento di caricamento desiderato usando un valore DWORD denominato LoadBehavior. Questo valore determina il modo in cui il componente aggiuntivo viene caricato dall'applicazione host ed è costituito da una combinazione dei valori seguenti:

  • 0 = Disconnetti: non viene caricato.
  • 1 = Connesso : viene caricato.
  • 2 = Bootload : caricamento all'avvio dell'applicazione.
  • 8 = DemandLoad - Carica solo quando richiesto dall'utente.
  • 16 = ConnectFirstTime - Carica una sola volta (all'avvio successivo).

Il valore tipico specificato è 0x03 (Connected | Bootload).

I componenti aggiuntivi che implementano IDTExtensibility2 devono specificare anche un valore DWORD denominato CommandLineSafe per indicare se i componenti aggiuntivi sono sicuri per le operazioni che non supportano un'interfaccia utente. Il valore 0x00 indica False e il valore 0x01 indica True.

Come compilare un componente aggiuntivo COM usando Visual C# .NET

Come accennato in precedenza, un componente aggiuntivo COM di Office è un server COM in-process attivato da un'applicazione di Office tramite il livello di runtime COM. Di conseguenza, lo sviluppo di un componente aggiuntivo COM in .NET richiede l'implementazione del componente aggiuntivo in .NET e quindi l'esposizione ai client COM (ovvero le applicazioni di Office) tramite il livello di interoperabilità COM.

Per creare un componente aggiuntivo COM in Visual C# .NET, seguire questa procedura:

  1. In Visual C# .NET creare un progetto libreria di classi.
  2. Aggiungere un riferimento alla libreria dei tipi che implementa IDTExtensibility2. L'assembly di interoperabilità primario per questo è già disponibile con il nome Extensibility.
  3. Aggiungere un riferimento alla libreria di oggetti di Microsoft Office. L'assembly di interoperabilità primario per questo è già disponibile con il nome Office.
  4. Creare una classe pubblica nella libreria di classi che implementa IDTExtensibility2.
  5. Dopo aver compilato la libreria di classi, registrare la libreria per l'interoperabilità COM. A tale scopo, generare un assembly denominato sicuro per questa libreria di classi e quindi registrarlo con l'interoperabilità COM. È possibile usare Regasm.exe per registrare un componente .NET per l'interoperabilità COM.
  6. Creare voci del Registro di sistema in modo che le applicazioni di Office possano riconoscere e caricare il componente aggiuntivo.

È possibile scegliere di completare tutti questi passaggi oppure creare un progetto .NET di tipo Componente aggiuntivo condiviso. Verrà avviata l'Estendibilità guidata, che consente di creare un componente aggiuntivo COM in .NET.

L'Estendibilità guidata crea un progetto di libreria di classi .NET di Visual C# insieme a una classe Connect che implementa l'interfaccia IDTExtensibility2. Viene generato anche lo scheletro di codice che implementa i membri vuoti di IDTExtensibility. Questo progetto contiene riferimenti agli assembly Extensibility e Office. Nelle impostazioni di compilazione del progetto è selezionata l'opzione Registra per l'interoperabilità COM. Il file della chiave assembly (con estensione snk) viene generato e viene fatto riferimento nell'attributo AssemblyKeyfile in Assemblyinfo.vb.

Insieme al progetto di libreria di classi, la procedura guidata genera un progetto di installazione che è possibile usare per distribuire il componente aggiuntivo COM in altri computer. È possibile rimuovere questo progetto, se lo si desidera.

Esempio dettagliato

  1. Nel menu File in Microsoft Visual Studio .NET fare clic su Nuovo e quindi su Progetto.

  2. Nella finestra di dialogo Nuovo progetto espandere Altri progetti in Tipi di progetto, selezionare Progetti di estendibilità e quindi selezionare il modello componente aggiuntivo condiviso.

  3. Digitare MyCOMAddin come nome del componente aggiuntivo e quindi fare clic su OK.

  4. Quando viene visualizzata l'Estendibilità guidata, seguire questa procedura:

    1. Nella pagina 1 selezionare Crea un componente aggiuntivo usando Visual C# e quindi fare clic su Avanti.

    2. Nella pagina 2 selezionare le applicazioni host seguenti e quindi fare clic su Avanti:

      • Microsoft Word
      • Microsoft PowerPoint
      • Microsoft Outlook
      • Microsoft Excel
      • Microsoft Access
    3. Nella pagina 3 specificare un nome e una descrizione per il componente aggiuntivo e quindi fare clic su Avanti.

      Nota Il nome e la descrizione del componente aggiuntivo vengono visualizzati nella finestra di dialogo Componente aggiuntivo COM nell'applicazione di Office.

    4. Nella pagina 4 selezionare tutte le opzioni disponibili e quindi fare clic su Avanti.

    5. Fare clic su Finish.

  5. Scegliere Aggiungi riferimento dal menu Progetto. Fare clic su System.Windows.Forms.DLL nell'elenco dei componenti, fare clic su Seleziona e quindi su OK.

  6. Aggiungere quanto segue all'elenco degli spazi dei nomi nella classe Connect:

    using System.Reflection;
    
  7. Aggiungere il membro seguente alla classe Connect:

    private CommandBarButton MyButton;
    
  8. Implementare il codice per i membri di IDTExtensibility2 nella classe Connect, come indicato di seguito:

    public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {
       applicationObject = application;
       addInInstance = addInInst;
    
    if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
       {
          OnStartupComplete(ref custom);
       }
    
    }
    
    public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) {
       if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
       {
          OnBeginShutdown(ref custom);
       }
       applicationObject = null;
    }
    
    public void OnAddInsUpdate(ref System.Array custom)
    {
    }
    
    public void OnStartupComplete(ref System.Array custom)
    {
       CommandBars oCommandBars;
       CommandBar oStandardBar;
    
    try
       {
       oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null);
       }
       catch(Exception)
       {
       // Outlook has the CommandBars collection on the Explorer object.
       object oActiveExplorer;
       oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);
       oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);
       }
    
    // Set up a custom button on the "Standard" commandbar.
       try
       {
       oStandardBar = oCommandBars["Standard"];        
       }
       catch(Exception)
       {
       // Access names its main toolbar Database.
       oStandardBar = oCommandBars["Database"];      
       }
    
    // In case the button was not deleted, use the exiting one.
       try
       {
       MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"];
       }
       catch(Exception)
       {
          object omissing = System.Reflection.Missing.Value ;
          MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing);
          MyButton.Caption = "My Custom Button";
          MyButton.Style = MsoButtonStyle.msoButtonCaption;
       }
    
    // The following items are optional, but recommended. 
       //The Tag property lets you quickly find the control 
       //and helps MSO keep track of it when more than
       //one application window is visible. The property is required
       //by some Office applications and should be provided.
       MyButton.Tag = "My Custom Button";
    
    // The OnAction property is optional but recommended. 
       //It should be set to the ProgID of the add-in, so that if
       //the add-in is not loaded when a user presses the button,
       //MSO loads the add-in automatically and then raises
       //the Click event for the add-in to handle. 
       MyButton.OnAction = "!<MyCOMAddin.Connect>";
    
    MyButton.Visible = true;
       MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click);
    
    object oName = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null);
    
    // Display a simple message to show which application you started in.
       System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString()   , "MyCOMAddin");
       oStandardBar = null;
       oCommandBars = null;
    }
    
    public void OnBeginShutdown(ref System.Array custom)
    {
       object omissing = System.Reflection.Missing.Value ;
       System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading.");
       MyButton.Delete(omissing);
       MyButton = null;
    }
    
    private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) {
       System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); }
    
  9. Compilare e testare il componente aggiuntivo COM. A tal fine, attenersi alla seguente procedura:

    1. Nel menu Compila fare clic su Compila soluzione. Si noti che la compilazione del componente aggiuntivo COM registra la classe .NET con l'interoperabilità COM.
    2. Avviare una delle applicazioni di Office selezionate come applicazioni host per il componente aggiuntivo, ad esempio Microsoft Word o Microsoft Excel.
    3. Dopo l'avvio del componente aggiuntivo, viene generato l'evento OnStartupComplete del componente aggiuntivo e viene visualizzato un messaggio. Chiudere la finestra di messaggio. Si noti che il componente aggiuntivo ha aggiunto un nuovo pulsante personalizzato con la didascalia "Pulsante personalizzato" alla barra degli strumenti standard.
    4. Fare clic sul pulsante Personalizzato. L'evento Click per il pulsante viene gestito dal componente aggiuntivo e viene visualizzata una finestra di messaggio. Chiudere la finestra di messaggio.
    5. Chiudere l'applicazione di Office.
    6. Quando si esce dall'applicazione, viene generato l'evento OnBeginShutDown e viene visualizzato un messaggio. Chiudere la finestra di messaggio per terminare la dimostrazione.