【问题标题】:Programmatically add function to existing C#-file with EnvDTE使用 EnvDTE 以编程方式将函数添加到现有 C# 文件
【发布时间】:2012-11-14 10:21:20
【问题描述】:

我想以编程方式将一个函数(一个 TestMethod)添加到现有的 C# 文件中。 经过一番谷歌搜索,我找到了库 EnvDTECodeModel.AddFunction-Method,但我找不到我想要的一个很好的例子。

我想在新创建的函数中添加一个带有代码的函数以及一个属性。像这样的:

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

谁能给我举个例子来说明如何做到这一点?

编辑:我想编辑一个 C# 文件,就像你编辑一个文本文件一样。我知道您可以使用 StreamWriter 来做到这一点,但是否有更好的方法来做到这一点?

【问题讨论】:

  • 您的意思是修改 C#(文本)文件还是 C# (.NET) 类?修改文本与修改编译后的代码完全不同。
  • 我的意思是一个 C# 文本文件。它用于生成测试文件。我可以用 StreamWriter 做到这一点,但我可能有更好的方法来做到这一点。
  • 您需要找到可以将代码解析为语法树的东西,然后调整该语法树以添加您的函数,然后从该语法树生成一个新文件。
  • Visual Studio 可以为他做到这一点(使用 EnvDTE)。无需重新发明轮子:-)

标签: c# visual-studio-2010 envdte


【解决方案1】:

EnvDTE 可能是要走的路。您可以开发 VisualStudio 加载项,然后修改 Exec 方法。在此方法中,您必须获取活动文档及其 ProjectItem。在这里您可以找到包含大量 CodeElement 的 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();");
            }
        }
    }

【讨论】:

  • 这就是我要找的!这比像文本文件一样编辑 cs 文件要好得多。非常感谢!
  • 这对我来说是一个很棒的起点!谢谢!另外值得注意的是能够做到SmartFormat 而不是缩进。它智能地格式化一系列代码,从调用 EditPoint 开始,到参数 TextPoint 结束。这是使用上述代码的示例:ep.Insert("string test = Helper.CodeExample();");tp.CreateEditPoint().SmartFormat(ep);
猜你喜欢
  • 2013-07-09
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2021-11-19
相关资源
最近更新 更多