2012-11-14 75 views
7

我想以編程方式將函數(TestMethod)添加到現有的C#文件。 經過一些谷歌搜索後,我找到了庫EnvDTECodeModel.AddFunction - 方法,但我找不到我想要的一個好例子。使用EnvDTE以編程方式將函數添加到現有的C#文件

我想添加一個代碼已經在新創建的函數中,也有一個屬性的函數。這樣的事情:

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

任何人都可以告訴我一個關於如何做到這一點的例子嗎?

編輯:我想編輯一個C#文件,就像編輯一個文本文件一樣。我知道你可以用StreamWriter做到這一點,但是有沒有更好的方法來做到這一點?

+0

你的意思修改C#(文本)文件或C#(.NET)類?修改文本與修改編譯代碼完全不同。 – larsmoa

+0

我的意思是一個C#文本文件。它用於生成測試文件。我可以用StreamWriter做到這一點,但我可能會有更好的方式來做到這一點。 – Mathieu

+0

您需要找到能夠將代碼解析到語法樹中的內容,然後調整該語法樹以添加您的函數,然後從該語法樹生成新文件。 –

回答

5

EnvDTE可以走的路。您可以開發VisualStudio加載項,然後修改Exec方法。在這種方法中,您必須獲取活動文檔及其ProjectItem。這是你找到包含很多CodeElements的CodeModel的地方。在這些元素中你必須找到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

相關問題