추가기능(Add-in) 만드는 법
VS .NET 2003은 개발에 필요한 많은 기능들을 제공해 주는 IDE(통합 개발 환경) 입니다.
그 편리함은 이루 말할 수 없지만 개발자들의 모든 요구를 충족시켜 줄 수는 없습니다.
그래서 VS .NET 2003에서는 개발자가 필요한 기능을 직접 만들어서 확장할 수 있는 프로그래밍 모델을 제공합니다. 이것이 바로 추가기능입니다.
아래는 MSDN에 나와있는 추가기능(Add-in)에 대한 설명입니다.
Visual Studio에서 개발자에게 거의 모든 작업을 수행할 수 있는 많은 도구와 기능을 제공하고는 있지만 개발자에 따라서는 보다 세부적이고 추가적인 제어를 위한 기능이 필요할 수 있습니다. 예를 들어, 반복적으로 수행하는 특정 작업 또는 일련의 작업을 자동화하려는 경우가 있습니다. 이를 위해 Visual Studio에서는 IDE(통합 개발 환경)를 확장하고 자동화할 수 있도록 자동화 모델이라는 풍부한 기능의 프로그래밍 모델을 제공합니다. 자동화 모델은 환경을 자동화할 수 있도록 할 뿐 아니라 확장성과 새로운 기능을 환경에 제공합니다.
아래 MSDN 에서 VS .NET의 추가기능에 대한 자세한 내용을 볼 수 있습니다.
따라서 추가기능에 대한 설명은 MSDN으로 대신하고자 합니다. 이 강좌는 활용 강좌이고.. 에… 또.. 사실 자세한 것은 저도 잘 모르기 때문에 말이죠..^^;
MSDN(추가기능 관련 url)
Visual Studio 환경 확장
http://msdn.microsoft.com/library/KOR/vsintro7/html/vxoriExtendingVisualStudioEnvironment.asp?frame=true
자동화 및 확장성 참조
http://msdn.microsoft.com/library/KOR/vsintro7/html/vxoriExtensibilityReference.asp?frame=true
지금부터 추가기능을 어떻게 만드는지 알아보겠습니다.
추가기능을 수동으로 만들어서 추가할 수도 있지만 VS .NET 2003에서 제공하는 추가 기능 마법사를 이용하면 쉽게 만들 수 있습니다.
1. 파일 > 새로만들기 > 프로젝트 > 기타 프로젝트 > 확장성 프로젝트 > Visual Studio .NET 추가 기능 선택
이름, 위치를 선택하고 확인 버튼을 클릭합니다.
마법사가 나타나는 것을 볼 수 있습니다.
중요한 부분만 설명할 테니 나머지 부분은 자신에게 맞게 선택하고 다음을 누르면 됩니다.
2. 추가 기능 옵션 선택
1. 추가 기능을 도구 메뉴에 표시할지 여부
2-1. 추가 기능에 모달 UI(사용자 인터페이스)를 사용하지 않도록 하여 명령줄 빌드에서 안전하게 사용할 수 있도록 할지 여부
2-2. 추가 기능을 시작하는 시기(VS .NET 이 실행될 때 추가기능을 로드 할지 여부)
우리는 1번 "예, '도구' 메뉴 항목을 만듭니다. 호스트 응용 프로그램이 시작될 때…" 를 선택해 보도록 하겠습니다.
3. 마침 버튼을 눌러 마법사를 마치면 아래와 같이 프로젝트가 생성됩니다.
추가기능 프로젝트와 설치 프로젝트가 생성돼있는 것을 볼 수 있습니다.
이제 추가기능의 전체적인 틀은 완성됐습니다. 우리는 원하는 기능만 구현하면 됩니다.
그 전에 마법사가 만들어 놓은 프로젝트와 소스를 좀 살펴 보도록 하겠습니다.
참조에 보면 낯선 놈들이 세 개가 추가돼있는 것이 보입니다. 이 놈들을 살펴보자면 말이죠.
EnvDTE
Visual Studio .NET 자동화 모델의 모든 개체와 멤버는 DTE 개체를 기반으로 합니다. Visual Studio .NET IDE를 대표하는 DTE 개체는 자동화 모델 계층 구조의 최상위 개체이며 EnvDTE라는 네임스페이스에 위치합니다. 이 네임스페이스는 "envdte"라는 .NET 어셈블리 이름으로 envdte.dll 파일에 포함되며, COM 형식 라이브러리는 "Microsoft Development Environment 7.0"이라는 이름으로 dte.olb 파일에 포함됩니다. (MSDN 발췌)
그렇습니다. 추가기능을 만들기 위해서는 DTE 개체가 필요하기 때문에 EnvDTE 에셈블리가 참조된 것입니다.
마법사에 의해서 생성된 Connect.cs 파일을 살펴보면 멤버 변수로 DTE 개체를 선언해 놓은 것을 볼 수 있습니다.
private _DTE applicationObject;
참고로 DTE 개체는 추가 기능을 만들 때 구현하는 OnConnection 메서드에서 제공합니다.
Extensibility
이 네임스페이스는 IDTExtensibility2 인터페이스를 포함하는데 IDTExtensibility2 인터페이스는 추가 기능이 로드, 언로드, 업데이트되는 경우 등에 발생하는 이벤트 알림을 호스팅합니다. (MSDN 발췌)
멤버로는 OnConnection, OnDisconnection 등이 있습니다.
메서드에 대한 설명은 아래에서 다시 다루겠습니다.
Office
Microsoft.Office.Core 네임스페이스의 _CommandBars, CommandBar, CommandBarControl 인터페이스의 멤버를 사용하여 VS .NET 메뉴에 추가기능 메뉴를 추가하기 위해서 참조되었습니다.
자~ 이제 Connect.cs 의 내용도 살펴 보도록 할까요.
먼저 클래스 정의 부분을 살펴보면 IDTExtensibility2, IDTCommandTarget 라는 인터페이스를 상속하고 있습니다.
public class Connect : Object, Extensibility.IDTExtensibility2, IDTCommandTarget
IDTExtensibility2 : 위에서 설명한대로 추가기능이 로드, 언로드, 업데이트되는 경우 등에 발생하는
이벤트를 처리하기 위함입니다.
IDTCommandTarget : AddNamedCommand 메서드로 추가된 명령을 처리하려면 이 인터페이스를
구현해야 합니다.
멤버는 다음과 같습니다.
Exec : AddNamedCommand 메서드를 사용하여 추가한 명령을 실행합니다.
QueryStatus : AddNamedCommand 메서드를 사용하여 추가한 명령의 현재 상태
(사용, 사용 안 함, 숨김 등)를 반환합니다.
IDTCommandTarget 인터페이스를 사용하면 개발 환경에서 명명된 명령을 구현할 수 있습니다. 또한 명령의 상태를 정의하고 명령을 실행할 수 있습니다.
AddNamedCommand 메서드를 사용하여 추가한 명령을 명령 창에 입력하면 명령 창에서는 먼저 IDTCommandTarget 인터페이스의 QueryStatus 메서드를 사용하여 해당 명령을 사용할 수 있는지 여부를 확인합니다. ExecuteCommand 메서드를 호출하는 경우에도 마찬가지입니다.
추가 기능에서 IDTExtensibility2와 함께 이 인터페이스를 구현하는 경우 추가 기능에서 만든 명명된 명령의 실행은 이 인터페이스로 직접 라우팅됩니다. (MSDN 발췌)
클래스 정의 부분에 대한 설명은 여기까지 하고 메서드로 넘어가 보도록 하겠습니다.
클래스 정의 부분을 설명할 때 나온 IDTExtensibility2 인터페이스를 기억하시나요? 이 인터페이스의 멤버를 구현해 놓은 놈들이 바로 OnConnection, OnDisconnection, OnAddInsUpdate, OnStartupComplete, OnBeginShutdown 입니다. 여기에서는 자주 쓰이는 앞에 두 놈만 설명하겠습니다.
public void OnConnection
추가 기능이 Visual Studio에 로드될 때마다 발생합니다. 따라서 이 곳에서 DTE 개체의 초기화 및 도구 메뉴에 추가기능 메뉴를 등록하는 작업이 이루어 집니다.
아래 코드가 바로 그 것이죠.
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
applicationObject = (_DTE)application; //DTE 개체 변수 초기화
addInInstance = (AddIn)addInInst; //추가기능(add-in) 개체 초기화
//추가 기능(add-in) 메뉴를 VS .NET 메뉴에 추가하는 부분
//사실 이 부분은 마법사에서 "예, '도구' 메뉴 항목을 만듭니다. 호스트 응용프로그램이
//시작될 때…"를 선택했기 때문에 추가된 코드 입니다. 선택하지 않았다면 아래 코드도
//생성되지 않습니다.
if(connectMode == Extensibility.ext_ConnectMode.ext_cm_UISetup)
{
object []contextGUIDS = new object[] { };
Commands commands = applicationObject.Commands;
_CommandBars commandBars = applicationObject.CommandBars;
try
{
Command command = commands.AddNamedCommand(addInInstance, "MyAddin1",
"MyAddin1", "Executes the command for MyAddin1", true, 59,
ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported
+ (int)vsCommandStatus.vsCommandStatusEnabled);
CommandBar commandBar = (CommandBar)commandBars["Tools"];
CommandBarControl commandBarControl = command.AddControl(commandBar, 1);
}
catch(System.Exception /*e*/)
{
}
}
}
|
public void OnDisconnection
Visual Studio에서 추가 기능이 언로드될 때마다 발생합니다.
클래스 정의 부분에서 설명한 IDTCommandTarget 인터페이스 멤버를 구현한 메서드들 입니다.
public void QueryStatus
지정한 명명된 명령의 현재 상태(사용, 사용 안 함, 숨김 등)를 반환합니다.
예를 들어 특정 언어(C#, VB.Net)를 사용할 때 혹은 텍스트를 선택했을 때 메뉴를 보이거나 숨기려 한다면 여기에 그 코드를 구현하면 됩니다.
public void Exec
지정한 명명된 명령을 실행합니다.
추가기능(add-in) 메뉴를 클릭했을 때 실행되는 메서드 입니다.
handled = false;
if(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "MyAddin1.Connect.MyAddin1")
{
//이 곳에 메뉴가 클릭됐을 때 실행할 구문을 추가하면 됩니다.
handled = true;
return;
}
}
|
Connect.cs 소스는 마법사 중에서 "추가 기능 옵션"의 옵션 선택에 따라서 조금씩 바뀝니다. 옵션에 따라서 필요한 코드가 추가되거나 제거 되는 것이죠.
전체적으로 정리하자면 추가기능을 구현하기 위해서는 다음과 같은 작업이 필요합니다.
1. DTE 개체 정의
2. IDTExtensibility2 인터페이스 구현
3. IDTCommandTarget 인터페이스 구현(UI를 제공할 경우)
여기까지 소스에 대한 설명이었습니다.
다시 실습으로 돌아가서 Connect.cs 파일에 원하는 기능을 구현해 보도록 하겠습니다.
우리는 메뉴를 클릭하면 메시지 박스에 “추가기능!!”이라는 메시지를 출력해보겠습니다.
우선 참조에 System.Windows.Forms를 추가합니다.
다음처럼 Exec 메서드에 코드를 추가합니다.
public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption,
ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "MyAddin1.Connect.MyAddin1")
{
System.Windows.Forms.MessageBox.Show("추가기능!!");
handled = true;
return;
}
}
}
|
이제 설치 프로젝트를 빌드합니다.
이제 여러분의 추가기능 설치프로젝트의 출력경로(추가기능프로젝트명\설치프로젝트명\debug)로 가서 Setup.exe를 실행해서 추가기능을 설치합니다. 이때 VS .NET은 모두 닫고 설치하세요.
VS .NET을 실행합니다. 도구 메뉴에 다음과 같이 여러분이 만든 추가기능이 추가돼있고 메뉴를 클릭하면 좀 전에 추가했던 코드가 실행되는 것을 확인할 수 있습니다.
여러분들은 여기까지 해보신 소감이 어떠신지요?
VS .NET 추가 기능 만드는 것을 어떻게 생각하셨을지 모르지만 저는 어려운 작업이라고 생각하고 있었죠. 근데 이렇게 간단하게 구현할 수 있다는 걸 알고 좀 허무했다고나 할까요? 뭐 그런 느낌이었습니다.
다음 강좌에는 실용적인 예제로 강좌를 만들어 보도록 하겠습니다.
DOWNLOAD : 강좌에서 사용된 소스를 다운로드 받으시려면 클릭하세요