2012-11-14 4 views
7

Я хочу программно добавить функцию (TestMethod) в существующий C# -файл. После некоторых поисковых запросов я нашел библиотеку EnvDTE и CodeModel.AddFunction -Method, но я не могу найти хороший пример того, что я хочу.Программно добавить функцию в существующий C# -файл с EnvDTE

Я хотел бы добавить функцию с кодом уже в этой вновь созданной функции, а также с атрибутом. Что-то вроде этого:

/// <summary> 
/// Documentation 
/// </summary> 
[TestMethod] 
public void TestMethod1() 
{ 
    string test = Helper.CodeExample(); 
} 

Может ли кто-нибудь показать мне пример о том, как это сделать?

EDIT: Я хочу отредактировать файл C#, как если бы вы отредактировали текстовый файл. Я знаю, что вы можете сделать это с помощью StreamWriter, но может быть, лучший способ сделать это?

+0

ли вы имеете в виду изменение файла C# (текст) или C# (.NET) класс? Изменение текста полностью отличается от изменения скомпилированного кода. – larsmoa

+0

Я имею в виду текстовый файл C#. Это для создания тестовых файлов. Я могу сделать это с помощью StreamWriter, но, хотя, возможно, это лучший способ сделать это. – Mathieu

+0

Вам нужно найти что-то, что может проанализировать код в дереве синтаксиса, а затем адаптировать это дерево синтаксиса, чтобы добавить вашу функцию, а затем сгенерировать новый файл из этого дерева синтаксиса. –

ответ

5

EnvDTE может быть путем. Вы можете разработать надстройку VisualStudio, а затем изменить метод Exec. В этом методе вы должны получить активный документ и его ProjectItem. Здесь вы найдете CodeModel, который содержит много CodeElements. Среди этих элементов вы должны найти CodeNamespace и внутри этого элемента CodeClass. Это объект, который реагирует на AddFunction, возвращающий новую CodeFunction, к которой вы можете добавить свой атрибут и код (это часть, которая мне не нравится слишком много, поскольку вы должны использовать EditPoint).

Это очень простой вариант Exec, что вы можете использовать в качестве отправной точки:

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) 
    { 
     handled = false; 
     if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) 
     { 
      handled = true; 
      if (commandName == "TestAddMethod.Connect.TestAddMethod") 
      { 
       Document activeDoc = _applicationObject.ActiveDocument; 
       if (activeDoc == null) 
        return; 
       ProjectItem prjItem = activeDoc.ProjectItem; 
       if (prjItem == null) 
        return; 
       FileCodeModel fcm = prjItem.FileCodeModel; 
       if (fcm == null) 
        return; 

       CodeElements ces = fcm.CodeElements; 
       // look for the namespace in the active document 
       CodeNamespace cns = null; 
       foreach (CodeElement ce in ces) 
       { 
        if (ce.Kind == vsCMElement.vsCMElementNamespace) 
        { 
         cns = ce as CodeNamespace; 
         break; 
        } 
       } 
       if (cns == null) 
        return; 
       ces = cns.Members; 
       if (ces == null) 
        return; 
       // look for the first class 
       CodeClass cls = null; 
       foreach (CodeElement ce in ces) 
       { 
        if (ce.Kind == vsCMElement.vsCMElementClass) 
        { 
         cls = ce as CodeClass; 
         break; 
        } 
       } 
       if (cls == null) 
        return; 
       CodeFunction cf = cls.AddFunction("TestMethod1", vsCMFunction.vsCMFunctionFunction, vsCMTypeRef.vsCMTypeRefVoid, -1, vsCMAccess.vsCMAccessPrivate); 
       cf.AddAttribute("TestMethod", "true"); 
       TextPoint tp = cf.GetStartPoint(vsCMPart.vsCMPartBody); 
       EditPoint ep = tp.CreateEditPoint(); 
       ep.Indent(); 
       ep.Indent(); 
       ep.Indent(); 
       ep.Insert("string test = Helper.CodeExample();"); 
      } 
     } 
    } 
+0

Это то, что я ищу! Это лучше, чем просто редактирование cs-файла, такого как текстовый файл. Большое спасибо! – Mathieu

+1

Это была потрясающая отправная точка для меня! Спасибо! Также стоит отметить, что вы можете делать «SmartFormat», а не отступы. Он интеллектуально форматирует диапазон кода, начинающийся с вызова «EditPoint» и заканчивая параметром «TextPoint». Вот пример с использованием приведенного выше кода: 'ep.Insert (" string test = Helper.CodeExample(); ");' 'tp.CreateEditPoint(). SmartFormat (ep);' – philt5252