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 를 가리키게 됩니다.
아래와 같이 트릭으로 문제를 해결할 수 있습니다.
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 개체에 대해 더 많은 버그에 대한 정보를 봤던 기억이 나는데, 관련 링크를 까묵어서…;;