Visual Studio Extensibility 라고 부르는 VSX를 Visual Studio 2010에서 Visual Studio 11로 업그레이드를 해야 하는데, Visual Studio 11버전부터 그리 어려운 작업이 아닙니다.

과거 VSX 프로젝트를 Visual Studio 2008에서 Visual Studio 2010으로 업그레이드하려면 좀 골치가 아팠습니다. 기존에는 코드 에디터 제어를 Visual Studio Native에서 제공하는 Interface를 사용했지만, Visual Studio 2010부터 코드 에디터가 WPF로 바뀌면서 이 부분은 모조리 변경해야 했거든요.

  

  

아시다시피 Visual Studio Gallery에 공개한 VSGesture for VS2008버전과 VSGesture for VS2010의 구현이 완전 달라졌을 정도니까요. 물론 이 확장 기능은 필자가 VSGESTURE.CODEPLEX.COM에 공개해 놓았으니 소스 코드도 받으실 수 있습니다.

  

Visual Studio 11로 VSX 업그레이드에 대한 더 자세한 내용은 다음의 문서를 참고하시기 바랍니다.

http://msdn.microsoft.com/en-us/library/hh567449(v=vs.110).aspx

  

일단 Visual Studio 11에서 프로젝트를 엽니다.

Visual Studio 11에서 프로젝트를 열어보니, 알아서 몇몇 파일들은 알아서 체크아웃이 되네요. 아마도 Resources 파일과 관련해서 뭔가가 바뀌었나 봅니다.

  

Source.Extension.VsixManifest 파일을 엽니다.

이 메니페스트 파일은 배포에 필요한 정보를 담고 있습니다. 확장 기능의 고유 GUID와 확장 기능 이름, 버전, 컨텐트 정보 등이 담겨져 있습니다.

그런데 그냥 XML 파일이 열리네요. Visual Studio 2010 SDK를 설치하면 그나마 GUI가 제공이 되었는데, 아직 Visual Studio 11 Beta SDK 라서 제공이 안되나 봅니다.

  

[Visual Studio 2010 SDK 의 GUI Manifest 구성 에디터]

  

어쨌든 XML 파일이 열리더라도 그리 어려운 작업은 아닙니다. 그냥 몇 가지 구성만 추가해 주면 됩니다.

  

SupportedProducts 구성 추가

XML 내용의 SupportedProducts 섹션에 다음과 같이 Visual Studio 11버전과 지원할 Edition 목록을 추가하면 됩니다.

  

  

어셈블리 참조를 추가해 줍니다.

이 어셈블리들은 Visual Studio 11 SDK 를 설치하시고, 다음의 경로에서 찾을 수 있습니다.

%ProgramFiles(x86)%\Microsoft Visual Studio 11.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0

  

  • Microsoft.VisualStudio.Editor.dll
  • Microsoft.VisualStudio.Language.Intellisense.dll
  • Microsoft.VisualStudio.Shell.10.0.immutable.dll
  • Microsoft.VisualStudio.Shell.11.0.immutable.dll
  • Microsoft.VisualStudio.Shell.11.0.dll

  

  

그 외에…

실제로 VSX의 기능에 따라 변경해 주어야 할 부분이 더 많더군요. 그 부분은 VSX 개발하시는 분들이 알아서 하시리라 믿습니다.^^

Posted by 땡초 POWERUMC

댓글을 달아 주세요

VSX(Visual Studio Extensibility) 는 Visual Studio 의 기능을 확장할 수 있는 SDK(Software Development Kit) 를 통해 툴의 기능을 확장할 수 있는 소프트웨어 개발 키트입니다. 잘 설계된 Visual Studio 의 확장 가능한 모델은 Visual Studio 2005 부터 비약적으로 발전했습니다. 그리하여 현재 Visual Studio 2010 은 MEF(Managed Extensibility Framework) 를 기반으로 하여 개발, 패키징, 배포에 이르러 훨씬 단순화된 새로운 확장 모델인 VSIX 를 내놓게 되었습니다.

Visual Studio 2003 부터 Visual Studio SDK 를 제공해 주었지만, Visual Studio 2003 버전에서는 확장 기능을 개발할 수 있는 그리 좋은 여건은 아니었습니다. 왜냐하면 Visual Studio 2003 의 Customizing Point 는 대부분 자동화 개체 모델인 DTE 에 굉장히 의존적이었습니다.

Visual Studio 2005 는 이전의 IDE 기반을 갈아엎었다고 할 수 있을 정도로 상당히 파격적인 모습으로 다가왔습니다. 사실 이때만해도 Visual Studio 2003 에 비해 너무 느려지지 않았냐는 불만을 상당히 많이 들었습니다. 하지만 개발자들의 하드웨어 스팩이 좋아지고, Visual Studio 2005 가 제공하는 다양한 기능은 안쓸래야 안쓸수 없었답니다. 그리고 Visual Studio 2005 SDK 는 2008 버전까지 고스란히 답습하고 있었습니다.

Visual Studio 2008 은 이제 .NET 개발의 국민 IDE 로 자리매김 하였습니다. 그리고 빠르게 많은 기업에서 Visual Studio 2008 과 .NET Framework 3.5 기반으로 마이그레이션을 하고 있습니다. (적어도 제 주변 대부분이..) 그리고 이 시점부터 Software Factories 개념을 도입한 Guidance Automation 과 Blueprints 등 Visual Studio 확장 기능들이 대거 모습을 드러내기 시작했습니다. (GA 는 2005 버전부터 등장했지만 실제 활성화된 시점은 개인적으로 2008 부터가 아닐까 생각합니다)

그렇다면 Visual Studio 2010… 이제는 IDE 환경의 지존을 논한다고 생각합니다. 광고성 멘트라고 생각하시면 그냥 스킵 하셔도 좋습니다. .NET Framework 는 더없이 탄탄해지고, 딱딱했던 IDE 환경은 UX 친화적인 면을 보여주기 위해 노력한 흔적이 엿보입니다. 그리고 Oslo, Velocity, Pex, T4 Templates, 미려해진 DSL Tools, 진정한 통합을 꿈꾸는 Team System, 그리고 이번 주제였던 정말 편한 개발 환경 확장을 제공해주는 VSX...

   

.NET 의 과거와 현재, 그리고 미래
http://blog.powerumc.kr/172

[T4] - 1. Code Generation 과 GA(Guidance AUtomation)
[.NET/Visual Studio] - [T4] - 1. Code Generation 과 GA(Guidance Automation)

[Blueprints] S+S Blueprints
[Software Development/Software Factory] - [Blueprints] S+S Blueprints


   

그럼 기존의 VSX 는 어떻게 IDE 도구를 확장하였을까요?

  • Visual Studio Macro
    VB 스크립트 언어를 이용하여 Visual Studio 의 자동화 개체 모델의 DTE 객체를 제어할 수 있습니다. 아무래도 스크립트 언어이다보니 개발의 편의성은 좋지만 배포와 코드 보안에 좀 떨뜨름합니다.

       

  • Visual Studio Addin
    기능적인 면에서 Visual Studio Macro 와 큰 차이는 없습니다만, 스크립트 언어가 아닌 C# 과 같은 Managed 언어로 개발이 가능합니다. 태생적으로 Visual Studio Macro 와 동일선상이기 때문에 Addin 의 독립적인 기능만으로는 확장에 한계는 있었습니다. 하지만, DTE 개체 모델을 통해 개발이 굉장히 쉽고, 배포 또한 단순하여 가장 많은 사랑을 받은 VSX 분야입니다.

       

  • Visual Studio Integration Package (이하 VSIP)
    Visual Studio 를 진정으로 통합할 수 있는 확장 방법입니다. Visual Studio 의 COM Interface 를 고스란히 사용할 수 있고, 이것을 이용하여 Visual Studio 의 모든 기능을 활용하고 확장할 수 있습니다. 실제로 Visual Studio 기능의 대부분이 VSIP 를 통해 개발이 되었고 Visual Studio 의 특징을 가장 잘 보여주는 Interface 들로 구성이 되어있습니다. 여러분이 잘 알고 있는 솔루션 탐색기, 오류 리스트, 팀 탐색기 등 셀 수 없을 정도의 많은 VSIP 들이 Visual Studio 에 포함되어 있습니다.

       

  • Visual Studio Shell Isolated
    Visual Studio Shell Isolated 는 Visual Studio 와 같은 Shell 을 제공하고 개발할 수 있는 방법입니다. VSIP 가 Visual Studio 확장 기능에 필요한 요소를 가르킨다면, Shell Isolated 는 VSIP 를 담는 그릇이 되겠군요. Visual Studio Shell Isolated 를 이용하게 되면 기존에 Visual Studio 에서 제공하는 여러 가지 인터페이스를 고스란히 사용할 수 있는 이점이 있습니다. 가량, Project Type, Intellisence 와 Microsoft 의 통합 빌드 솔루션인 MSBuild 등 다양한 기능을 곧바로 사용할 수 있다는 장점이 있는 것이죠.

       

  • Visual Studio Language Package
    Visual Studio 에서 사용할 수 있는 언어를 개발할 수 있습니다. 기본적으로 C#, VB.NET, C++ 등을 사용할 수 있지만 PHP, RoR, Native C 등의 언어를 개발할 수 있도록 하고, 이미 Visual Studio for PHP, Visual Studio for RoR 가 상용화 되었고, Visual Studio for C 는 Visual Studio SDK 예제로도 포함이 되어 있답니다.


       
  • Domain-Specific Language Package
    도메인에 특화된 언어를 개발할 수 있는 방법을 제공합니다. 일반적으로 IT 조직과 개발 조직은 서로가 사용하는 언어가 다릅니다. 즉, 경영진과 실무진과 같은 물과 기름의 관계를 이해시키기 위한 언어로써, 이미 Visual Studio 에서 광범위하게 사용되고 있는 방법입니다.

 

  • Help Integration
    MS HELP 2.0 을 이용하여 Microsoft Document Explorer 의 콘텐츠를 추가할 수 있는 방법입니다. Microsoft Document Explorer 는 일반적으로 Visual Studio 도움말로 생각하시면 됩니다. 이곳에 콘텐츠를 추가하기 위해 Setup Wizard 를 제공하고, 쉽게 Visual Studio 도움말에 자사 또는 자신의 콘텐츠를 추가할 수 있습니다.

       

어휴,, 정말 다양한 방법으로 Visual Studio 를 확장하는 방법을 제공해 주는군요. 이러한 아키텍처는 Visual Studio 2005 부터 제대로 뿌리를 내렸는데, 그 중 일부분은 Visual Studio 2010 에서 좀 더 획기적으로 변신을 합니다.

변신을 하면서 기존의 COM 기반의 인터페이스는 더 이상 WPF 기반의 어플리케이션에서 상당수 비호환적인 면이 있고, 한계점을 드러내지 않았나 생각을 해봅니다. 실제로 기존의 인터페이스는 WPF 의 Managed 환경에서 더 이상 호환할 수 없어집니다. WPF 기반의 IDE 환경에서는 새로운 인터페이스가 필요했고, MEF 를 도입함으로써 새로운 확장 가능한 모델이 필요했습니다. 바로 그것이 새로운 확장 가능한 모델인 VSIX 입니다.

VSIX 는 기존의 IDE 확장 모델과 새로운 MEF 기반의 확장 기능을 개발부터 패키징, 배포까지 통합할 수 있는 방법을 제공해 줍니다. 뿐만 아니라 기존의 확장 기능과 새로운 MEF 기반의 확장 기능을 통합하고 연동까지 할 수 있으니 이것이야 말로 누이 좋고 매부 좋은 일이 아닐까 합니다.

   

이제부터 위의 다양한 확장 기능을 개발하는 방법을 시작하여 VSIX 에 이르기 까지 한번 짚고 넘어가볼 예정입니다. 아직까지 국내에서는 이러한 희귀한 분야를 다루는 곳도 흔치 않고, 관심이 있더라도 정보가 부족하여 어느 정도 종점을 찍고 포기하는 분들도 많이 있습니다. 아마 이 연재를 통해서 Visual Studio 에 보다 관심을 갖고 널리 기술을 알리는 좋은 기회가 되지 않을까 생각을 하면서, 연재를 기대해 주세요.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

 

지난 6월 10일 VSTS 2010 팀에서 진행한 MEF(Managed Extensibility Framework) 세미나에서 보여드린 데모를 조금 수정하여 Visual Studio Gallery 에 공개하였습니다.

Visual Studio 2010 이 WPF 기반의 IDE 환경으로 탈바꿈하면서 특히 코드 에디터 쪽은 WPF 의 기능을 유감없이 보여주었습니다. 특히 코드 에디터는 MEF 를 통해 대부분의 기능이 만들어졌고, 이것을 확장할 수 있는 기능을 만드는 것이 얼마나 편해졌는지 보여주기 위한 데모였습니다.

세미나에서도 설명했지만 현재 Visual Studio 2008 까지 버전에서 이러한 확장 기능을 개발하기 위해서는 굉장히 많은 단계를 거쳐야 합니다. Visual Studio 2008 까지는 COM 을 기반으로 한 IDE 이기 때문에 적용되는 기술만 나열해도 절대 단순하지 않은 과정을 거쳐야 합니다. 마우스와 키보드와 같은 장치의 이벤트를 핸들링 해야 하고, GDI+ 를 이용해 화면에 드로잉을 하고 잔상과 깜빡임을 없애기 위해 더블 버퍼링 등의 기법이 조합되어야 했습니다. 그리고 나은 사용자 인터페이스를 위해 많은 기교를 부려야만 했죠.

   

멀리서 프레젠테이션을 시청하는 분들도 커서의 위치를 잘 보이도록 화살표가 커서를 따라 다닙니다. 
 

 

Visual Studio Gallery

Umc.Core.Tools.MousePresentationTracker.v1.0

   

   

현재는 단순하게 마우스를 따라다니는 데모를 급 개조했지만, 나중에는 생각해 놓은 기능들을 추가하려고 합니다. 어쨌든 이전에 공개했던 VSGesture 와 다른 컨셉으로 프레젠테이션을 위한 도구로 점차 기능이 추가될 예정입니다.

   

'Umc Projects > MousePresentationTracker' 카테고리의 다른 글

MousePresentationTracker.v1.0  (0) 2009.07.17
Posted by 땡초 POWERUMC

댓글을 달아 주세요

Visual Studio Extensibility(VSX) 에 관련해서 몇 가지 버그를 알려드리고자 합니다.
 
1. VSX 의 이벤트가 먹통이 된다
 
이 부분은 아무래도 VSX 의 실행 주기에 대한 내용인 것 같습니다. 하지만 코드 자체로만 보면 아무런 문제가 없는 코드지요.
 
public void InitDteEvent()
{
        CommandEvents allEvents = xxxxUtil.GetEvents(this.DTE2, Constants.GUID_ALL_EVENT, 0);
        allEvents.AfterExecute += (guid, id, customIn, customOut) =>
               {
                       string name = DTE2.Commands.Item(guid, id).Name;
                       Trace.Write(
                              string.Format("Command {0} invoked - Guid: {1}, ID: {2}\n", name, guid, id));
               };
}
 
위의 코드를 볼 때, 분명 CommandEvents 는 DTE Instance 의 Refer 이고, 그 Refer Object 에게 이벤트를 할당하였을 때 이벤트가 발생해야 합니다.
 
결과를 먼저 알려드리자면, “최초 VSX 로드시 이벤트는 발생합니다.”, 하지만 아무 솔루션을 열고 난 이후엔, “더 이상 이벤트가 발생하지 않습니다”. 이러한 동작을 미루어 볼 때, VS Package 의 동작과 유사합니다.
 
어찌되었던, 이러한 코드는 아래와 같이 코드를 변경해 주시면 됩니다.
 
CommandEvents allEvents;
public void InitDteEvent()
{
        this.allEvents = xxxxUtil.GetEvents(this.DTE2, Constants.GUID_ALL_EVENT, 0);
        this.allEvents.AfterExecute += (guid, id, customIn, customOut) =>
               {
                       string name = DTE2.Commands.Item(guid, id).Name;
                       Trace.Write(
                              string.Format("Command {0} invoked - Guid: {1}, ID: {2}\n", name, guid, id));
               };
}
 
즉, 위의 코드처럼 allEvents 를 Class 의 지역변수로 빼시면, 더 이상 솔루션 로드 후에도 이벤트가 먹통이 되는 현상을 방지할 수 있습니다.
 
 
2. Project Template 을 추가한 후에 값이 null 이 반환된다
 
Project Template 을 솔루션 폴더에 추가하는 코드입니다.
 
folder.AddFromTemplate(template, Path.Combine(path, projectUniqueName), projectUniqueName);
 
위의 AddFromTemplate 의 시그너쳐는
 
[DispId(5)]
Project AddFromTemplate(string FileName, string Destination, string ProjectName);
 
이렇게 Project 개체를 리턴하도록 되어 있습니다.
 
하지만, 항상 이 메서드의 리턴은 Null 이 됩니다. 그렇기 때문에, 상식적으로 현재 생성된 Project Template 의 개체를 가져올 방법이 없습니다.
 
트릭이라고 해야할까요? AddFromTemplate 의 메서드가 실행되고 나면, SelectedItem 은 AddFromTemplate 으로 생성된 Project 를 가리키게 됩니다.
 
아래와 같이 트릭으로 문제를 해결할 수 있습니다.
 
DTE2.SelectedItems
 
 
3. ComVisible 은 마지막에 설정하라.
 
Project 개체의 Properties 프로퍼티를 통해 Project 의 속성을 가져오거나 설정할 수 있습니다. 이 개체를 통해 프로젝트의 속성을 다양하게 바꿀 수 있지만, 문제는 또 생깁니다. 점점 갈수록 어이없는 문제군요 ^^;
 
만약, Strong Key 와 Key File 과 ComVisible 속성을 변경한다고 할 때, ComVisible 의 값을 먼저 변경하고, Strong Key 값을 변경하게 되면, ComVisible 값은 원래의 값으로 원복 됩니다.
 
만약, 이러한 버그가 당신 앞에 펼쳐진다면,,, 원인 모를… 정말 답답했지만, 이 문제를 해결하기 위해선 값의 설정 순서를 바꾸시면 됩니다.
 
Strong Key >> Key File >> ComVisible
 
순서대로 값을 설정하시면 됩니다.
 
 
4. LINQ Query 개체가 초기화 되는 문제 ( 대박! )
 
정말 이건 대박이랍니다. 하하하! 먼저 코드를 보겠습니다.
 
var query                             = commentList.Where(o => o.Hotkey == selection.Text); // 결과는반드시 Null 아닙니다!!
if (query.Count() >= 1 )
{
        selection.Delete(1);// << Text Document 조작하는메서드
        text = query.Single().Content;    // << query Null
}
 
컬렉션의 값을 Where 하는것인데, 위의 빨간 라인의 코드를 만나게 되면, query 의 값이 Null 반환이 됩니다.
 
디버깅을 통해 보면
 
1.      query 값은 null 이 아니고, 값이 있습니다.
2.      query.Count() 는 분명 1개 이상의 값입니다.
3.      selection.Delete(1); 를 수행합니다.
4.      3번이 실행되는 즉시, query 가 null 이 됩니다.
 
정말 미치고 팔짝,, 뛰는 노릇입니다. 어찌되었건 우회방법을 통해서 해결했습니다만,,, 할말을 잃게 하는 버그인 것 같네요.
 
 
이 외에도, DTE 개체에 대해 더 많은 버그에 대한 정보를 봤던 기억이 나는데, 관련 링크를 까묵어서…;;

Posted by 땡초 POWERUMC

댓글을 달아 주세요