67

For a small community discussion, what are some essential Visual Studio macros you use?

I just started learning about them, and want to hear what some of you can't live without.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BBetances
  • 925
  • 1
  • 14
  • 23
  • 36
    Can't disagree more with this question being closed. It's extremely constructive and a great question. – David Morton Sep 27 '11 at 17:11
  • 7
    I agree. This was a useful topic and contains the answer I was looking for – SturmUndDrang May 29 '12 at 09:00
  • 1
    In VS 2012, the macro editor has been removed. That's the bad news. The good news is, you can use basically the same code in the language of your choice, by creating an add-in. Create a Visual Studio Add-in project, which will contain the boilerplate code you need. When you test, VS 2012 will fire up a separate instance of VS 2012 with your add-in installed. When you're ready to actually deploy, go to `My Documents\Visual Studio 2012\Addins`. There, for your project `whatever`, put the `whatever.dll` for your add-in, as well as the `whatever.AddIn` file from the main project directory. – Ryan Lundy Sep 05 '12 at 19:12
  • 2
    I've posted instructions here on how to create an add-in: [Alternative to Macros in Visual Studio 2012](http://stackoverflow.com/questions/12027485/alternative-to-macros-in-visual-studio-2012/12394986#12394986) – Ryan Lundy Sep 13 '12 at 19:16
  • 3
    Yes, stackoverflow.com community needs to revise how things are done. Some of the most popular questions are closed. – TheLegendaryCopyCoder Mar 18 '14 at 07:38
  • This properly belongs in [Dcoumentation](http://meta.stackoverflow.com/questions/303865/warlords-of-documentation-a-proposed-expansion-of-stack-overflow) – MSalters Oct 02 '15 at 12:01

14 Answers14

31

I add buttons on the toolbar for the following 3 macros. Each will take the currently selected text in any file and google it (or MSDN-it, or spell-check-it). Make up a nifty icon for the toolbar for extra style-points.

Private Const BROWSER_PATH As String = "C:\Program Files\Mozilla Firefox\firefox.exe"

Sub SearchGoogle()
    Dim cmd As String
    cmd = String.Format("{0} http://www.google.com/search?hl-en&q={1}", BROWSER_PATH, DTE.ActiveDocument.Selection.Text)
    Shell(cmd, AppWinStyle.NormalFocus)
End Sub

Sub SearchMSDN()
    Dim cmd As String
    cmd = String.Format("{0} http://www.google.com/search?hl-en&q={1}+site%3Amsdn.microsoft.com", BROWSER_PATH, DTE.ActiveDocument.Selection.Text)
    Shell(cmd, AppWinStyle.NormalFocus)
End Sub

Sub SpellCheck()
    Dim cmd As String
    cmd = String.Format("{0} http://www.spellcheck.net/cgi-bin/spell.exe?action=CHECKWORD&string={1}", BROWSER_PATH, DTE.ActiveDocument.Selection.Text)
    Shell(cmd, AppWinStyle.NormalFocus)
End Sub
Aardvark
  • 8,474
  • 7
  • 46
  • 64
25

Show build duration in the Output window

Put this code in your EnvironmentEvents module. This will write the duration directly to the build window for any action on a solution (build, rebuild, clean, deploy).

You can change the IsBuild function to specify the actions you want to see this information for.

Dim buildStart As Date

Private Function IsBuild(ByVal scope As EnvDTE.vsBuildScope, ByVal action As EnvDTE.vsBuildAction) As Boolean
    Return scope = vsBuildScope.vsBuildScopeSolution
End Function

Private Sub BuildEvents_OnBuildBegin(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildBegin
    If (IsBuild(Scope, Action)) Then
        buildStart = Date.Now
    End If
End Sub

Private Sub BuildEvents_OnBuildDone(ByVal Scope As EnvDTE.vsBuildScope, ByVal Action As EnvDTE.vsBuildAction) Handles BuildEvents.OnBuildDone
    If (IsBuild(Scope, Action)) Then
        Dim buildTime = Date.Now - buildStart
        WriteToBuildWindow(String.Format("Build time: {0}", buildTime.ToString))
    End If
End Sub

Private Sub WriteToBuildWindow(ByVal message As String)
    Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
    Dim ow As OutputWindow = CType(win.Object, OutputWindow)
    For Each owPane As OutputWindowPane In ow.OutputWindowPanes
        If (owPane.Name.Equals("Build")) Then
            owPane.OutputString(message)
            Exit For
        End If
    Next
End Sub
Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
  • 4
    I have something similar, but I was wondering if there is a way to make a running total that is persistent, so I can keep track of how much of my life I spend compiling. – Dolphin May 10 '11 at 19:10
  • Sure, just take the timespan and store it in a database. As far as I know, you can run pretty much any code in a macro. So just write code to store the latest TimeSpan, and then to retrieve the total and display that instead. – Ryan Lundy May 10 '11 at 19:19
  • Little late to the party, but wanted to thank you for this one as it's just what I was looking for. On a sidenote: you can use `ow.OutputWindowPanes.Item("Build").OutputString(message)` instead of the `For Each`. – Chrono Nov 07 '12 at 08:45
  • For some reason this does not work for me, do I have to enable the calling of the EnvironmentEvents somehow? – Ian Ringrose Dec 21 '12 at 13:23
  • @IanRingrose, what version of Visual Studio are you on? Macros were removed in VS 2012. If you can't get the macro to work, you could try creating an add-in. [See this answer](http://stackoverflow.com/questions/12027485/alternative-to-macros-in-visual-studio-2012/12394986#12394986). – Ryan Lundy Dec 21 '12 at 14:28
  • @Kyralessa I am still on 2010, however I found the free version of VSCommands for Visual Studio 2010 that gave me the infomation I needed on build times. – Ian Ringrose Dec 21 '12 at 21:19
  • @IanRingrose, if you still want to try with the macros, make sure you have this code *in* the EnvironmentEvents module. And make sure you have the Handles clauses in place, as in the code above. The macro editor in every version of Visual Studio was pretty flaky, though, and it was hard to see simple things like compile errors. I guess they preferred to take it out rather than fix it. – Ryan Lundy Dec 21 '12 at 21:22
  • This page is also useful to get the events working. You need to do what is says in the "To add a new event procedure to the Class Name combo box" section and then unload and reload the macro project for it to work. http://technet.microsoft.com/en-us/windows/0b27f9kz%28v=vs.85%29.aspx – cedd May 22 '14 at 16:00
14

Show the start page after you close a solution (but keep Visual Studio open)

Put this code in your EnvironmentEvents module:

Private Sub SolutionEvents_AfterClosing() Handles SolutionEvents.AfterClosing
    DTE.ExecuteCommand("View.StartPage")
End Sub


Hide the start page after you open a solution

Put this code in your EnvironmentEvents module:

Private Sub SolutionEvents_Opened() Handles SolutionEvents.Opened
    Dim startPageGuid As String = "{387CB18D-6153-4156-9257-9AC3F9207BBE}"
    Dim startPage As EnvDTE.Window = DTE.Windows.Item(startPageGuid)
    If startPage IsNot Nothing Then startPage.Close()
End Sub


These two together will cause your Start Page to hide itself when you open a solution. When you close the solution, the Start Page comes back.

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
  • 11
    Who really needs the start page? – kizzx2 Sep 25 '10 at 17:11
  • 2
    VS 2010 added a "Close page after project load" option on the start page, so the close macro is no longer needed. They have that and "Show page on startup", but for strange reasons unknown to me, there is no "Show page after solution close" option, which is the matching opposite of "Close page after project load". Who needs the start page? I use it to pin Recent Projects. AFAIK, it's the only place you can pin recent projects/solutions (in 2010). You can't pin the items in the File -> Recent Projects and Solutions menu, so it's not reliable for long-term use. – minnow Apr 19 '13 at 15:38
13

I use the following lesser-known shortcuts very often:

  • Ctrl+Enter: Insert a blank line above the current line (and place the cursor there)
  • Ctrl+Shift+Enter: Insert a blank line below the current line (and place the cursor there)
  • Ctrl+Shift+V: Cycles the clipboard ring
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
9

Outlining: Collapse to definitions but expand regions

Are you working in one of those shops that insists on regions around everything, so that when you collapse to definitions, you can't see any code?

What you really need is a collapse-to-definitions-but-expand-regions macro, like this one:

Sub CollapseToDefinitionsButExpandAllRegions()
    DTE.ExecuteCommand("Edit.CollapsetoDefinitions")
    DTE.SuppressUI = True
    Dim objSelection As TextSelection = DTE.ActiveDocument.Selection
    objSelection.StartOfDocument()
    Do While objSelection.FindText("#region", 
        vsFindOptions.vsFindOptionsMatchInHiddenText)
    Loop
    objSelection.StartOfDocument()
    DTE.SuppressUI = False
End Sub

Put this in a regular macro module, assign it to a hot key, and your code is back.

(Except...if you work with some really nefarious individuals who put regions inside methods, this will unfortunately expand those methods. If anybody knows a way to write this to avoid that, feel free to edit.)

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
8

Insert GUID, great for WiX work, add to menu as button or as key shortcut.

Sub InsertGuid()
    Dim objTextSelection As TextSelection
    objTextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
    objTextSelection.Text = System.Guid.NewGuid.ToString.ToUpper(New System.Globalization.CultureInfo("en", False))
End Sub

Organise usings for all .cs files in a solution - Original Author: djpark.

Sub OrganizeSolution()
    Dim sol As Solution = DTE.Solution
    For i As Integer = 1 To sol.Projects.Count
        OrganizeProject(sol.Projects.Item(i))
    Next
End Sub

Private Sub OrganizeProject(ByVal proj As Project)
    For i As Integer = 1 To proj.ProjectItems.Count
        OrganizeProjectItem(proj.ProjectItems.Item(i))
    Next
End Sub

Private Sub OrganizeProjectItem(ByVal projectItem As ProjectItem)
    Dim fileIsOpen As Boolean = False
    If projectItem.Kind = Constants.vsProjectItemKindPhysicalFile Then
        'If this is a c# file             
        If projectItem.Name.LastIndexOf(".cs") = projectItem.Name.Length - 3 Then
            'Set flag to true if file is already open                 
            fileIsOpen = projectItem.IsOpen
            Dim window As Window = projectItem.Open(Constants.vsViewKindCode)
            window.Activate()
            projectItem.Document.DTE.ExecuteCommand("Edit.RemoveAndSort")
            'Only close the file if it was not already open                 
            If Not fileIsOpen Then
                window.Close(vsSaveChanges.vsSaveChangesYes)
            End If
        End If
    End If
    'Be sure to apply RemoveAndSort on all of the ProjectItems.         
    If Not projectItem.ProjectItems Is Nothing Then
        For i As Integer = 1 To projectItem.ProjectItems.Count
            OrganizeProjectItem(projectItem.ProjectItems.Item(i))
        Next
    End If
    'Apply RemoveAndSort on a SubProject if it exists.         
    If Not projectItem.SubProject Is Nothing Then
        OrganizeProject(projectItem.SubProject)
    End If
End Sub
si618
  • 16,580
  • 12
  • 67
  • 84
5

Collapse all nodes of the Solution panel, very useful especially for big projects:

    Public Module CollapseAllNodes
    Sub RunCollapseAllNodes()
        Dim UIHSolutionExplorer As UIHierarchy
        UIHSolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()

        ' Check if there is any open solution 
        If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then
            Return
        End If

        ' Get the top node (the name of the solution) 
        Dim UIHSolutionRootNode As UIHierarchyItem
        UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)

        CloseRecursif(UIHSolutionRootNode)

        ' Select the solution node, or else when you click 
        ' on the solution windows scrollbar, it will synchronize the open document 
        ' with the tree and pop out the corresponding node which is probably not 
        ' what you want. 
        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
    End Sub

    Function CloseRecursif(ByRef element)
        For Each UIHChild In element.UIHierarchyItems()
            CloseRecursif(UIHChild)

            If (UIHChild.UIHierarchyItems.Expanded = True) Then
                UIHChild.UIHierarchyItems.Expanded = False
            End If

        Next
    End Function
End Module
Olivier Payen
  • 15,198
  • 7
  • 41
  • 70
4

I use Jeff's FormatToHtml macros if I'm going to be pasting a code example into a blog post or an email.

Glenn Lang
  • 41
  • 1
  • 3
4

I work with dual monitors, and I find Sharon's layout-switching macro (from a 1 monitor to a 2 monitor layout) totally invaluable. When you need to be referencing a web page or other program while typing a bit of code, Ctrl-Alt-1 to switch to a one monitor layout for your Visual Studio windows. Once you're done, Ctrl-Alt-2 to switch to your two monitor layout and get all your windows back. Awesome!

http://www.invisible-city.com/sharon/2008/06/workstation-hack-visual-studio-on-2.html

womp
  • 115,835
  • 26
  • 236
  • 269
2

Not a macro on its own, but useful:

Public Sub WriteToOutputWindow(ByVal pane as String, ByVal Msg As String)
    Dim owPane As OutputWindowPane

    Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
    Dim ow As OutputWindow = win.Object
    Try
        owPane = ow.OutputWindowPanes.Item(pane)
    Catch
        owPane = ow.OutputWindowPanes.Add(pane)
    End Try
    If Not owPane Is Nothing Then
        owPane.Activate()
        owPane.OutputString(Msg & vbCrLf)
    End If
End Sub
Benjol
  • 63,995
  • 54
  • 186
  • 268
1

I'm currently working on two different projects with different coding standards, one that uses tabs for line beginnings and another that uses spaces. This macro will toggle between which standard is used based on which environment is currently active:

Public Sub ToggleTabs()
  If DTE.ActiveDocument.Language = "CSharp" Then
      Dim currentSetting As Boolean = DTE.Properties("TextEditor", "CSharp").Item("InsertTabs").Value
      DTE.Properties("TextEditor", "CSharp").Item("InsertTabs").Value = Not currentSetting
  End If

  If DTE.ActiveDocument.Language = "SQL" Then
      Dim currentSQLSetting As Boolean = DTE.Properties("TextEditor", "SQL").Item("InsertTabs").Value
      DTE.Properties("TextEditor", "SQL").Item("InsertTabs").Value = Not currentSQLSetting
  End If

  If DTE.ActiveDocument.Language = "HTML" Then
      Dim currentHTMLSetting As Boolean = DTE.Properties("TextEditor", "HTML").Item("InsertTabs").Value
      DTE.Properties("TextEditor", "HTML").Item("InsertTabs").Value = Not currentHTMLSetting
  End If

  If DTE.ActiveDocument.Language = "JScript" Then
      Dim currentJScriptSetting As Boolean = DTE.Properties("TextEditor", "JScript").Item("InsertTabs").Value
      DTE.Properties("TextEditor", "JScript").Item("InsertTabs").Value = Not currentJScriptSetting
  End If

End Sub
yanigisawa
  • 731
  • 1
  • 8
  • 19
1

I mapped ctrl-shift-G to a macro that generates a GUID in registry format - this is useful for editing IDL

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
0

I used to employ a lot of macros in VS 2002/2003. One example would be Region creation - I always like my classes to be divided into the following regions - "Private members", "Public Properties", "Public Methods" and "Private methods". So, I have a macro mapped to a shortcut key that creates these regions in any new class file.

Refactoring support in VS 2005/2008 (and the facility of adding common code snippets) as well as the use of Addins like DXCore and SlickEdit allow me to work without having to create too many macros anymore.

Cerebrus
  • 25,615
  • 8
  • 56
  • 70
0

I couldn't let this question go without mentioning this one. It even has a video to show how to install and use it. This macro simply allows you to create the nested files in the solution explorer (like resources.resx).

Edit: Updated the link

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216