다른 Office 솔루션에서 응용 프로그램 수준 추가 기능의 코드 호출

업데이트: 2010년 9월

추가 기능의 개체를 다른 Microsoft Office 솔루션을 비롯한 다른 솔루션에 노출할 수 있습니다. 이렇게 하면 추가 기능에서 제공하는 서비스를 다른 Office 솔루션에서 사용할 수 있게 하려는 경우에 유용합니다. 예를 들어 웹 서비스에서 금융 데이터에 대한 계산을 수행하는 Microsoft Office Excel용 추가 기능이 있는 경우 다른 솔루션에서 런타임에 Excel 추가 기능을 호출하여 이러한 계산을 수행할 수 있습니다.

적용 대상: 이 항목의 정보는 Microsoft Office 2010 및 2007 Microsoft Office system의 응용 프로그램 수준 프로젝트에 적용됩니다. 자세한 내용은 Office 응용 프로그램 및 프로젝트 형식에 따라 사용 가능한 기능을 참조하십시오.

이 프로세스의 두 가지 주요 단계는 다음과 같습니다.

  • 추가 기능에서 다른 솔루션에 개체를 노출합니다.

  • 다른 솔루션에서 추가 기능이 노출한 개체에 액세스하고 이 개체의 멤버를 호출합니다.

추가 기능의 코드를 호출할 수 있는 솔루션 유형

다음 유형의 솔루션에 추가 기능의 개체를 노출할 수 있습니다.

  • 추가 기능과 동일한 응용 프로그램 프로세스에 로드되는 문서의 VBA(Visual Basic for Applications) 코드

  • 추가 기능과 동일한 응용 프로그램 프로세스에 로드되는 문서 수준 사용자 지정

  • Visual Studio에서 Office 프로젝트 템플릿을 사용하여 만든 다른 추가 기능

  • COM 추가 기능. 즉, IDTExtensibility2 인터페이스를 직접 구현하는 추가 기능

  • 추가 기능과는 다른 프로세스에서 실행되는 모든 솔루션. 이러한 유형의 솔루션을 out-of-process 클라이언트라고도 합니다. 여기에는 Windows Forms 또는 콘솔 응용 프로그램과 같이 Office 응용 프로그램을 자동화하는 응용 프로그램이나 다른 프로세스에 로드된 추가 기능이 포함됩니다.

다른 솔루션에 개체 노출

추가 기능의 개체를 다른 솔루션에 노출하려면 추가 기능에서 다음 단계를 수행합니다.

  1. 다른 솔루션에 노출할 클래스를 정의합니다.

  2. ThisAddIn 클래스의 RequestComAddInAutomationService 메서드를 재정의합니다. 다른 솔루션에 노출할 클래스의 인스턴스를 반환합니다.

다른 솔루션에 노출할 클래스 정의

최소한, 노출할 클래스는 public이어야 하고, ComVisibleAttribute 특성이 true로 설정되어 있어야 하며, IDispatch 인터페이스를 노출해야 합니다.

IDispatch 인터페이스를 노출하는 데 권장되는 방법은 다음 단계를 수행하는 것입니다.

  1. 다른 솔루션에 노출할 멤버를 선언하는 인터페이스를 정의합니다. 추가 기능 프로젝트에서 이 인터페이스를 정의할 수 있습니다. 그러나 클래스를 VBA 이외의 솔루션에 노출하려는 경우에는 추가 기능을 호출하는 솔루션이 추가 기능 프로젝트를 참조하지 않고도 이 인터페이스를 참조할 수 있도록 인터페이스를 별도의 클래스 라이브러리 프로젝트에 정의할 수도 있습니다.

  2. 이 인터페이스에 ComVisibleAttribute 특성을 적용하고 이 특성을 true로 설정합니다.

  3. 이 인터페이스를 구현하도록 클래스를 수정합니다.

  4. 클래스에 ClassInterfaceAttribute 특성을 적용하고 이 특성을 ClassInterfaceType 열거형의 None 값으로 설정합니다.

  5. 클래스를 out-of-process 클라이언트에 노출하려면 다음 작업도 수행해야 합니다.

    • StandardOleMarshalObject에서 클래스를 파생시킵니다. 자세한 내용은 Out-of-Process 클라이언트에 클래스 노출을 참조하십시오.

    • 인터페이스를 정의하는 프로젝트에서 COM Interop 등록 속성을 설정합니다. 이 속성은 클라이언트에서 초기 바인딩을 사용하여 추가 기능을 호출할 수 있도록 하려는 경우에만 필요합니다. 자세한 내용은 방법: 구성 요소 COM Interop 등록을 참조하십시오.

다음 코드 예제에서는 다른 솔루션에서 호출할 수 있는 ImportData 메서드가 있는 AddInUtilities 클래스를 보여 줍니다. 보다 큰 연습의 컨텍스트에서 이 코드를 보려면 연습: VBA에서 응용 프로그램 수준 추가 기능의 코드 호출을 참조하십시오.

<ComVisible(True)> _
Public Interface IAddInUtilities
    Sub ImportData()
End Interface

<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class AddInUtilities
    Implements IAddInUtilities

    ' This method tries to write a string to cell A1 in the active worksheet.
    Public Sub ImportData() Implements IAddInUtilities.ImportData

        Dim activeWorksheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet

        If activeWorksheet IsNot Nothing Then
            Dim range1 As Excel.Range = activeWorksheet.Range("A1")
            range1.Value2 = "This is my data"
        End If
    End Sub
End Class
[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";
        }
    }
}

VBA에 클래스 노출

위에 나온 단계를 수행하면 VBA 코드에서는 인터페이스에 선언된 메서드만 호출할 수 있습니다. 클래스가 Object 등의 기본 클래스에서 가져온 메서드를 비롯하여 클래스의 다른 메서드는 VBA 코드에서 호출할 수 없습니다.

또는 ClassInterfaceAttribute 특성을 ClassInterfaceType 열거형의 AutoDispatch 또는 AutoDual 값으로 설정하여 IDispatch 인터페이스를 노출할 수도 있습니다. 이렇게 할 경우 별도의 인터페이스에 메서드를 선언할 필요가 없습니다. 하지만 Object 등의 기본 클래스에서 가져온 메서드를 비롯하여 클래스의 public 메서드와 static이 아닌 메서드를 VBA 코드에서 호출할 수 있습니다. 또한 초기 바인딩을 사용하는 out-of-process 클라이언트에서는 클래스를 호출할 수 없습니다.

Out-of-Process 클라이언트에 클래스 노출

추가 기능의 클래스를 out-of-process 클라이언트에 노출하려면 out-of-process 클라이언트에서 노출된 추가 기능 개체를 호출할 수 있도록 클래스를 StandardOleMarshalObject에서 파생시켜야 합니다. 그러지 않으면 out-of-process 클라이언트에서 노출된 개체의 인스턴스를 가져오려고 할 때 예기치 않게 실패할 수 있습니다.

Office 응용 프로그램의 개체 모델은 항상 주 UI 스레드에서 호출해야 하는데 out-of-process에서 개체를 호출할 때는 호출이 임의의 RPC(원격 프로시저 호출)에 도착하기 때문입니다. .NET Framework의 COM 마샬링 메커니즘은 스레드를 전환하지 않으며, 주 UI 스레드 대신 들어오는 RPC 스레드에서 개체에 대한 호출을 마샬링하려고 합니다. 개체가 StandardOleMarshalObject에서 파생된 클래스의 인스턴스인 경우 개체에 대한 들어오는 호출은 노출된 개체가 만들어진 스레드로 자동으로 마샬링되며, 이 스레드가 호스트 응용 프로그램의 주 UI 스레드가 됩니다.

Office 솔루션에서의 스레드 사용에 대한 자세한 내용은 Office의 스레딩 지원을 참조하십시오.

RequestComAddInAutomationService 메서드 재정의

다음 코드 예제에서는 추가 기능의 ThisAddIn 클래스에서 RequestComAddInAutomationService를 재정의하는 방법을 보여 줍니다. 이 예제에서는 다른 솔루션에 노출할 AddInUtilities라는 클래스가 정의되어 있다고 가정합니다. 보다 큰 연습의 컨텍스트에서 이 코드를 보려면 연습: VBA에서 응용 프로그램 수준 추가 기능의 코드 호출을 참조하십시오.

Private utilities As AddInUtilities

Protected Overrides Function RequestComAddInAutomationService() As Object
    If utilities Is Nothing Then
        utilities = New AddInUtilities()
    End If
    Return utilities
End Function
private AddInUtilities utilities;

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

    return utilities;
}

추가 기능이 로드되면 Microsoft Visual Studio Tools for Office Runtime에서는 RequestComAddInAutomationService 메서드를 호출합니다. 해당 런타임에서는 추가 기능을 나타내는 COMAddIn 개체의 Object 속성에 반환된 개체를 할당합니다. 이 COMAddIn 개체는 다른 Office 솔루션과 Office를 자동화하는 솔루션에서 사용할 수 있습니다.

다른 솔루션에서 개체 액세스

추가 기능의 노출된 개체를 호출하려면 클라이언트 솔루션에서 다음 단계를 수행합니다.

  1. 노출된 추가 기능을 나타내는 COMAddIn 개체를 가져옵니다. 클라이언트는 호스트 Office 응용 프로그램의 개체 모델에서 Application.COMAddIns 속성을 사용하여 사용 가능한 모든 추가 기능에 액세스할 수 있습니다.

  2. COMAddIn 개체의 Object 속성에 액세스합니다. 이 속성은 추가 기능의 노출된 개체를 반환합니다.

  3. 노출된 개체의 멤버를 호출합니다.

COMAddIn.Object 속성의 반환 값을 사용하는 방법은 VBA 클라이언트와 VBA가 아닌 클라이언트의 경우에 각각 다릅니다. out-of-process 클라이언트의 경우 발생할 수 있는 경합 상태를 방지하려면 추가 코드가 필요합니다.

VBA 솔루션에서 개체 액세스

다음 코드 예제에서는 VBA를 사용하여 추가 기능에서 노출된 메서드를 호출하는 방법을 보여 줍니다. 이 VBA 매크로는 ExcelImportData라는 추가 기능에 정의된 ImportData라는 메서드를 호출합니다. 보다 큰 연습의 컨텍스트에서 이 코드를 보려면 연습: VBA에서 응용 프로그램 수준 추가 기능의 코드 호출을 참조하십시오.

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

VBA가 아닌 솔루션에서 개체 액세스

VBA가 아닌 솔루션에서는 COMAddIn.Object 속성 값을 해당 솔루션이 구현하는 인터페이스로 캐스팅해야 합니다. 그러면 노출된 메서드를 이 인터페이스 개체에서 호출할 수 있습니다. 다음 코드 예제에서는 Visual Studio의 Office 개발자 도구를 사용하여 만든 다른 추가 기능에서 ImportData 메서드를 호출하는 방법을 보여 줍니다.

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

이 예제에서 COMAddIn.Object 속성 값을 IAddInUtilities 인터페이스 대신 AddInUtilities 클래스로 캐스팅하려고 하면 코드에서 InvalidCastException이 throw됩니다.

참고 항목

작업

연습: VBA에서 응용 프로그램 수준 추가 기능의 코드 호출

방법: Visual Studio에서 Office 프로젝트 만들기

개념

확장성 인터페이스를 사용하여 UI 기능 사용자 지정

응용 프로그램 수준 추가 기능 아키텍처

기타 리소스

응용 프로그램 수준 추가 기능 프로그래밍

Office 솔루션 개발

변경 기록

날짜

변경 내용

이유

2010년 9월

내용 구성을 개선하고 중복된 정보를 제거했습니다.

향상된 기능 관련 정보