2012-11-14 9 views
7

既存のC#ファイルに関数(TestMethod)をプログラムで追加します。 いくつかのグーグルで私は図書館EnvDTECodeModel.AddFunction -Methodを見つけましたが、私が欲しいものの良い例は見つかりません。EnvDTEで既存のC#ファイルに関数をプログラムで追加する

私はすでに新しく作成された関数にも、属性とともにコードを持つ関数を追加したいと思います。このようなもの:

/// <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を取得する必要があります。これは、多くのCodeElementsを含むCodeModelを見つける場所です。これらの要素の中で、CodeNamespaceを見つけ、この要素の内部にCodeClassを配置する必要があります。これは、あなたの属性とコードを追加できる新しいCodeFunctionを返すAddFunctionに応答するオブジェクトです(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

関連する問題