You can get good info from VSX forums (Visual Studio Extensibility).
The DTE can be used to add, disable, and remove elements of the IDE to tightly control the user experience, which is an excellent objective.
Here's some quick info from my tinkering...
DTE can be used to insert source directly into the project, compile and run. With VSTA’s support for WPF, XAML forms, even the UI can be inserted as source text. It could be as simple as something like this (context: inside the VstaDesignTimeIntegration class of sample):
//1. Insert source code
EnvDTE.ProjectItem appSrc = this.macroProject.ProjectItems[0];
If (appSrc.Name.Equals("AppAddIn.cs"))
{
EnvDTE.TextSelection sel = (EnvDTE.TextSelection)appSrc.Document.Selection;
sel.StartOfDocument(false);
sel.Text = "// pass in contents of project as text here\n";
}
//2. Save and build…
IVstaHostAdapter hostAdapter = (IVstaHostAdapter)this.macroProject.get_Extender("VSTAHostAdapter2007");
string hostItemFileName = hostAdapter.ProjectHostItems[0].CodeFilePath;
string hostItemClassName = hostAdapter.ProjectHostItems[0].ProgrammingModelHostItem.Identifier;
EnvDTE.ProjectItem hostItemProjectItem =
this.macroProject.ProjectItems.Item(Path.GetFileName(hostItemFileName));
hostItemProjectItem.Save(null);
this.macroProject.DTE.Solution.SolutionBuild.Build(true);
====
To give some more context and let you try this out yourself, below is some drop in code to ‘spit’ the following class source code into ‘AppAddin.cs’ in the Addin project:
public class Chess
{
// This is the move function
public int Move(bool IsOK)
{
int a = 1;
int b = 3;
return a + b; //return default(int);
}
}
==
You can use the EnvDTE.DTE dte instance in VstaDesignTimeIntegration.cs file, to add this code to an addin project.
Here’s example code that does this.
public void SpitEventCode()
{
EnsureIDE();
System.Diagnostics.Debug.Assert(this.dte != null);
System.Diagnostics.Debug.Assert(macroProject != null);
// Add a comment to AppAddin.cs.
EnvDTE.ProjectItem appSrc = null;
foreach (EnvDTE.ProjectItem pitem in macroProject.ProjectItems)
{
if (pitem.Name.Equals("AppAddIn.cs"))
{
appSrc = pitem;
break;
}
}
EnvDTE80.FileCodeModel2 model = (EnvDTE80.FileCodeModel2)appSrc.FileCodeModel;
foreach (EnvDTE.CodeElement codeElement in model.CodeElements)
{
ExamineCodeElement(codeElement, 3);
}
EnvDTE.TextSelection sel = (EnvDTE.TextSelection)appSrc.Document.Selection;
sel.StartOfDocument(false);
sel.NewLine(1);
sel.LineUp(false, 1);
sel.Text = "// New comment\n";
}
// recursively examine code elements
private void ExamineCodeElement(EnvDTE.CodeElement codeElement, int tabs)
{
tabs++;
try
{
Console.WriteLine(new string('\t', tabs) + "{0} {1}", codeElement.Name, codeElement.Kind.ToString());
// if this is a namespace, add a class to it.
if (codeElement.Kind == EnvDTE.vsCMElement.vsCMElementNamespace)
{
AddClassToNamespace((EnvDTE.CodeNamespace)codeElement);
}
foreach (EnvDTE.CodeElement childElement in codeElement.Children)
{
ExamineCodeElement(childElement, tabs);
}
}
catch
{
Console.WriteLine(new string('\t', tabs) + "codeElement without name: {0}", codeElement.Kind.ToString());
}
}
// add a class to the given namespace
private void AddClassToNamespace(EnvDTE.CodeNamespace ns)
{
// add a class
EnvDTE80.CodeClass2 chess = (EnvDTE80.CodeClass2)ns.AddClass("Chess", -1, null, null, EnvDTE.vsCMAccess.vsCMAccessPublic);
// add a function with a parameter and a comment
EnvDTE80.CodeFunction2 move = (EnvDTE80.CodeFunction2)chess.AddFunction("Move", EnvDTE.vsCMFunction.vsCMFunctionFunction, "int", -1, EnvDTE.vsCMAccess.vsCMAccessPublic, null);
move.AddParameter("IsOK", "bool", -1);
move.Comment = "This is the move function";
// add some text to the body of the function
EnvDTE80.EditPoint2 editPoint = (EnvDTE80.EditPoint2)move.GetStartPoint(EnvDTE.vsCMPart.vsCMPartBody).CreateEditPoint();
editPoint.Indent(null, 0);
editPoint.Insert("int a = 1;");
editPoint.InsertNewLine(1);
editPoint.Indent(null, 3);
editPoint.Insert("int b = 3;");
editPoint.InsertNewLine(2);
editPoint.Indent(null, 3);
editPoint.Insert("return a + b; //");
}