Llamar al código en complementos de VSTO desde otras soluciones de Office

Puede exponer un objeto en su complemento VSTO para otras soluciones, incluidas otras soluciones de Microsoft Office. Esto resulta útil si su complemento VSTO proporciona un servicio que quiera habilitar para que lo usen otras soluciones. Por ejemplo, si tiene un complemento VSTO para Microsoft Office Excel que realiza cálculos sobre datos financieros de un servicio web, otras soluciones pueden realizar estos cálculos llamando al complemento VSTO de Excel en tiempo de ejecución.

Se aplica a: La información de este tema se aplica a los proyectos de complemento de VSTO. Para obtener más información, consulte Características disponibles por aplicación de Office lication y tipo de proyecto.

Hay dos pasos principales en este proceso:

  • En el complemento VSTO, exponga un objeto a otras soluciones.

  • En otra solución, acceda al objeto expuesto por el complemento VSTP y llame a los miembros del objeto.

Tipos de soluciones que pueden llamar al código en un complemento

Puede exponer un objeto en un complemento de VSTO a los siguientes tipos de soluciones:

  • Código de Visual Basic para Aplicaciones (VBA) en un documento que se carga en el mismo proceso de aplicación que el complemento VSTO.

  • Personalizaciones de nivel de documento que se cargan en el mismo proceso de aplicación que el complemento VSTO.

  • Otros complementos VSTO creados con plantillas de proyecto de Office en Visual Studio.

  • Complementos COM VSTO (es decir, complementos que implementan la interfaz IDTExtensibility2 directamente).

  • Cualquier solución que se ejecute en un proceso diferente que el complemento VSTO (estos tipos de soluciones también se llaman clientes fuera de proceso). Estas soluciones incluyen aplicaciones que automatizan una aplicación de Office, como Windows Forms o la aplicación de consola, y complementos VSTO que se cargan en un proceso diferente.

Exponer objetos a otras soluciones

Para exponer un objeto del complemento VSTO en otras soluciones, siga estos pasos en el complemento VSTO:

  1. Defina una clase que quiera exponer a otras soluciones.

  2. Invalide el método RequestComAddInAutomationService en la clase ThisAddIn . Devuelva una instancia de la clase que quiere exponer a otras soluciones.

Definir la clase que desea exponer a otras soluciones

Como mínimo, la clase que quiera exponer tiene que ser pública, debe tener el atributo ComVisibleAttribute establecido en truey debe exponer la interfaz IDispatch .

La manera recomendada de exponer la interfaz IDispatch es realizar los siguientes pasos:

  1. Defina una interfaz que declare los miembros que quiere exponer a otras soluciones. Puede definir esta interfaz en su proyecto de complemento VSTO. Sin embargo, puede que quiera definir esta interfaz en un proyecto de biblioteca de clase diferente, si quiere exponer la clase a soluciones que no son VBA; de ese modo, las soluciones que llaman al complemento VSTO pueden hacer referencia a la interfaz sin hacer referencia al proyecto de complemento VSTO.

  2. Aplique el atributo ComVisibleAttribute a esta interfaz y establezca el atributo en true.

  3. Modifique la clase para implementar esta interfaz.

  4. Aplique el ClassInterfaceAttribute atributo a la clase y establezca este atributo en el valor None de la ClassInterfaceType enumeración.

  5. Si desea exponer esta clase a clientes fuera de proceso, es posible que también tenga que hacer lo siguiente:

    • Derive la clase de StandardOleMarshalObject. Para obtener más información, consulte Exponer clases a clientes fuera de proceso.

    • Establezca la propiedad Registrar para interoperabilidad COM en el proyecto donde define la interfaz. Esta propiedad solo es necesaria si desea permitir que los clientes usen el enlace anticipado para llamar al complemento VSTO.

    El siguiente ejemplo de código muestra una clase AddInUtilities con un método ImportData al que otras soluciones pueden llamar. Para ver este código en el contexto de un tutorial más grande, consulte Tutorial: Llamar al código en un complemento vsTO desde VBA.

    [ComVisible(true)]
    public interface IAddInUtilities
    {
        void ImportData();
    }
    
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddInUtilities : IAddInUtilities
    {
        // This method tries to write a string to cell A1 in the active worksheet.
        public void ImportData()
        {
            Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet;
    
            if (activeWorksheet != null)
            {
                Excel.Range range1 = activeWorksheet.get_Range("A1", System.Type.Missing);
                range1.Value2 = "This is my data";
            }
        }
    }
    

Exposición de clases a VBA

Cuando realice los pasos indicados arriba, el código VBA podrá llamar solo a los métodos que declare en la interfaz. El código VBA no puede llamar a ningún otro método de la clase, incluidos los métodos que la clase obtiene a partir de clases base, como Object.

Como alternativa, puede exponer la interfaz IDispatch estableciendo el ClassInterfaceAttribute atributo en el valor AutoDispatch o AutoDual de la ClassInterfaceType enumeración. Si expone la interfaz, no tiene que declarar los métodos en una interfaz independiente. Sin embargo, el código VBA puede llamar a cualquier método público y no estático de su clase, incluidos los métodos obtenidos a partir de clases base tales como Object. Además, los clientes fuera de proceso que usan enlace temprano no pueden llamar a su clase.

Exposición de clases a clientes fuera de proceso

Si quiere exponer una clase de su complemento de VSTO a clientes fuera de proceso, debe derivar la clase de StandardOleMarshalObject para asegurarse de que los clientes fuera de proceso puedan llamar al objeto de complemento de VSTO expuesto. De lo contrario, se podrían producir errores inesperados al intentar obtener una instancia del objeto expuesto en un cliente fuera de proceso.

Este error se debe a que todas las llamadas al modelo de objetos de una aplicación de Office lication deben realizarse en el subproceso principal de la interfaz de usuario, pero las llamadas de un cliente fuera de proceso al objeto llegarán a un subproceso RPC arbitrario (llamada a procedimiento remoto). El mecanismo de cálculo de referencias COM en .NET Framework no cambiará los subprocesos y, en cambio, intentará calcular las referencias de la llamada al objeto en el subproceso de RPC entrante en lugar del subproceso principal de interfaz de usuario. Si el objeto es una instancia de una clase que deriva de StandardOleMarshalObject, el cálculo de las referencias de las llamadas entrantes al objeto se realizará en el subproceso donde se creó el objeto expuesto, que será el subproceso principal de interfaz de usuario de la aplicación host.

Para obtener más información sobre el uso de subprocesos en soluciones de Office, vea Compatibilidad con subprocesos en Office.

Invalidación del método RequestComAddInAutomationService

El ejemplo de código siguiente muestra cómo invalidar RequestComAddInAutomationService en la clase ThisAddIn del complemento de VSTO. En el ejemplo se supone que ha definido una clase denominada AddInUtilities que desea exponer a otras soluciones. Para ver este código en el contexto de un tutorial más grande, consulte Tutorial: Llamar al código en un complemento vsTO desde VBA.

private AddInUtilities utilities;

protected override object RequestComAddInAutomationService()
{
    if (utilities == null)
        utilities = new AddInUtilities();

    return utilities;
}

Cuando se carga el complemento de VSTO, el Visual Studio Tools para Office tiempo de ejecución llama al RequestComAddInAutomationService método . El tiempo de ejecución asigna el objeto devuelto a la propiedad COMAddIn.Object de un COMAddIn objeto que representa el complemento de VSTO. Este objeto COMAddIn está disponible para otras soluciones de Office y para soluciones que automatizan Office.

Acceso a objetos desde otras soluciones

Para llamar al objeto expuesto en el complemento de VSTO, siga estos pasos en la solución cliente:

  1. Obtenga el objeto COMAddIn que representa el complemento de VSTO expuesto. Los clientes pueden acceder a todos los complementos de VSTO disponibles usando la propiedad Application.COMAddIns del modelo de objetos de la aplicación host de Office.

  2. Obtenga acceso a la propiedad COMAddIn.Object del COMAddIn objeto . Esta propiedad devuelve el objeto expuesto desde el complemento de VSTO.

  3. Llame a los miembros del objeto expuesto.

    La forma en que se usa el valor devuelto de la propiedad COMAddIn.Object es diferente para los clientes de VBA y los clientes que no son de VBA. En los clientes fuera de proceso, es necesario código adicional para evitar una posible condición de carrera.

Acceso a objetos desde soluciones de VBA

En el ejemplo de código siguiente se muestra cómo usar VBA para llamar a un método expuesto por un complemento de VSTO. Esta macro de VBA llama a un método denominado ImportData que se define en un complemento de VSTO denominado ExcelImportData. Para ver este código en el contexto de un tutorial más grande, consulte Tutorial: Llamar al código en un complemento vsTO desde VBA.

Sub CallVSTOMethod()
    Dim addIn As COMAddIn
    Dim automationObject As Object
    Set addIn = Application.COMAddIns("ExcelImportData")
    Set automationObject = addIn.Object
    automationObject.ImportData
End Sub

Acceso a objetos desde soluciones que no son de VBA

En una solución que no sea de VBA, debe convertir el valor de la propiedad COMAddIn.Object en la interfaz que implementa y, a continuación, puede llamar a los métodos expuestos en el objeto de interfaz. El ejemplo de código siguiente muestra cómo llamar al método ImportData desde un complemento de VSTO diferente que se creó usando las herramientas de desarrollador de Office en Visual Studio.

object addInName = "ExcelImportData";
Office.COMAddIn addIn = Globals.ThisAddIn.Application.COMAddIns.Item(ref addInName);
ExcelImportData.IAddInUtilities utilities = (ExcelImportData.IAddInUtilities)addIn.Object;
utilities.ImportData();

En este ejemplo, si intenta convertir el valor de la propiedad COMAddIn.Object en la AddInUtilities clase en lugar de la IAddInUtilities interfaz, el código producirá un InvalidCastException.