بنقرة واحدة
macro-dte-api
Use EnvDTE80.DTE2 inside Macros .csx files to inspect and automate Visual Studio
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use EnvDTE80.DTE2 inside Macros .csx files to inspect and automate Visual Studio
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
{what this skill teaches agents}
Troubleshoot Macros .csx scripts: command names, null state, timing, and runtime vs IntelliSense
Use the Community.VisualStudio.Toolkit facade from inside Macros .csx files
Trigger syntax for Macros .csx files: events, commands, filters, and header edits
How to write .csx macros for Visual Studio automation in the Macros repo
{what this skill teaches agents}
| name | macro-dte-api |
| description | Use EnvDTE80.DTE2 inside Macros .csx files to inspect and automate Visual Studio |
| domain | visual-studio-macros |
| confidence | high |
| source | derived from MacroGlobals, Helpers, docs, and DTE-based macro samples |
Use DTE inside a macro when helper methods are not enough and you need direct Visual Studio automation state.
Use this skill when the macro needs the active document, text selection, solution state, windows, debugger state, or direct command execution through the DTE automation model.
Do not use this skill for building a VS extension. This is only about using the already-injected DTE object from inside a .csx macro.
DTE globalInside a macro, DTE is the host Visual Studio automation root:
EnvDTE80.DTE2 dte = DTE;
Reference: https://learn.microsoft.com/en-us/dotnet/api/envdte80.dte2
Start here when a macro acts on the current file:
var doc = DTE.ActiveDocument;
if (doc == null)
{
await VS.StatusBar.ShowMessageAsync("No active document");
return;
}
TextSelectionCast Selection to EnvDTE.TextSelection:
var sel = DTE.ActiveDocument?.Selection as EnvDTE.TextSelection;
if (sel == null)
{
await VS.StatusBar.ShowMessageAsync("No text editor is active");
return;
}
sel.Insert(sel.Text.ToUpperInvariant(), (int)EnvDTE.vsInsertFlags.vsInsertFlagsInsertAtStart);
If you only need typing, caret movement, or selection, prefer helpers like TypeAsync, MoveCaretAsync, and SelectAsync.
Use DTE for solution-wide context:
if (DTE.Solution?.IsOpen == true)
{
string solutionName = DTE.Solution.FullName;
int projectCount = DTE.Solution.Projects?.Count ?? 0;
await VS.StatusBar.ShowMessageAsync($"{solutionName} has {projectCount} project(s)");
}
var state = DTE.Solution.SolutionBuild.BuildState;
if (state == EnvDTE.vsBuildState.vsBuildStateInProgress)
{
await VS.MessageBox.ShowWarningAsync("Macros", "Build still running");
return;
}
DTE.ExecuteCommand("View.ErrorList");
DTE.ExecuteCommand("Edit.FormatDocument");
If you want the macro vocabulary to stay consistent, await ExecuteCommandAsync("Edit.FormatDocument") is also correct.
var activeWindow = DTE.ActiveWindow;
if (activeWindow != null)
{
await VS.StatusBar.ShowMessageAsync($"Active window: {activeWindow.Caption}");
}
var mode = DTE.Debugger.CurrentMode;
if (mode == EnvDTE.dbgDebugMode.dbgBreakMode)
{
await VS.StatusBar.ShowMessageAsync("Debugger is in break mode");
}
Treat DTE as a UI-thread API.
Helper methods such as TypeAsync, MoveCaretAsync, SelectAsync, ExecuteCommandAsync, RunCommandAsync, and OpenFileAsync switch to the UI thread for you before touching DTE or shell services.
Practical guidance:
DTE access for reads or advanced editor automationTask.Runnull for documents, selections, and windowsvar sel = DTE.ActiveDocument?.Selection as EnvDTE.TextSelection;
if (sel?.IsEmpty == false)
{
await VS.StatusBar.ShowMessageAsync($"Selection length: {sel.Text.Length}");
}
if (DTE.ActiveDocument != null)
{
DTE.ExecuteCommand("File.SaveSelectedItems");
}
string? path = DTE.ActiveDocument?.FullName;
if (!string.IsNullOrEmpty(path))
{
await VS.StatusBar.ShowMessageAsync(path);
}
DTE.ActiveDocument or DTE.ActiveDocument?.Selection as EnvDTE.TextSelectionDTE.Solution.SolutionBuild.BuildState for build-aware branchingVS.StatusBar or VS.MessageBox to explain why the macro did nothing