8

関数 (TestMethod) を既存の C# ファイルにプログラムで追加したいと考えています。いくつかのグーグル検索の後、ライブラリEnvDTECodeModel.AddFunctionメソッドを見つけましたが、必要なものの良い例が見つかりません。

新しく作成された関数に既にコードがあり、属性もある関数を追加したいと思います。このようなもの:

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

これを行う方法の例を誰かに見せてもらえますか?

EDIT : テキスト ファイルを編集するように、C# ファイルを編集したい。StreamWriter を使用してこれを行うことができることは知っていますが、これを行うためのより良い方法はありますか?

4

1 に答える 1

7

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();");
            }
        }
    }
于 2012-11-15T09:27:59.127 に答える