Awesome Visual Studio Macros [closed] - visual-studio

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
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.

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

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

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.

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

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.)

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

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

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

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

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

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

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

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.

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

Related

Is there any way to save the checkbox's state of a program made in visual basic 6.0

I have made(designed) a program in Visual Basic 6.0,it consists of around 100 checkboxes ,the program does not require any code just a yes/no checkbox type program , but I want to save the checkbox state ,so that if a check box is in yes state then after restarting the program it's state remains conserved .
I have read about
My.Settings.Save but I dont know how to use it , I am using Visual Basic 6.0.
Create keys in Registry, save each checkbox value on their checkbox Change event and load the status of each of them in the form Initialize event code.
Option Explicit
Private Const MyApp As String = "My Own App" 'put here your application name
Private Const Sett As String = "Settings"
Private Sub CheckBox1_Change()
Dim chkBoxStatus As String
chkBoxStatus = "CheckBox1"
If Me.CheckBox1.value = True Then
SaveSetting MyApp, Sett, chkBoxStatus, CStr(True)
Else
SaveSetting MyApp, Sett, chkBoxStatus, CStr(False)
End If
End Sub
Do the same for all your check boxes.
And then:
Private Sub UserForm_Initialize() 'I do not remember well if VB6 uses Form_Initialize... You must adapt it accordingly.
Dim regValue As String
regValue = GetSetting(MyApp, Sett, "CheckBox1", "No value")
If regValue <> "No value" Then Me.CheckBox1.value = CBool(regValue)
'do the same for all checkboxes in discussion
'.
'.
End Sub
"No value" is returned if no value has been set in Registry (yet)...
Well, I would have made all checkboxes a control array and would save their sate in a text file in some hidden place, like C:\Users\UserName\AppData\Local. It would be a pretty small code.

Google Drive SDK - Populate .NET TreeView with Google Drive directory structure

I'm building a VB.NET Google Drive file explorer application for reasons that you probably do not care about. I'm using the google drive v2 sdk, and I'm trying to populate a tree view control with a user's entire Google Drive directory structure (not files, just folders.) My code is working fine, however, as I feared, it is taking several minutes for users that have a whole lot of nested folders. I am using a background worker thread to populate the treeview using a delegate function. Can anyone suggest a more efficient way of doing this?
NewPopulate() is called from my code to create the background worker threads. Start here:
Private Sub NewPopulate()
TreeView1.Nodes.Add(ActiveUser.Email, ActiveUser.Email)
bwPopulateTree = New BackgroundWorker
AddHandler bwPopulateTree.DoWork, AddressOf PopulateTreeStart
AddHandler bwPopulateTree.RunWorkerCompleted, AddressOf PopulateTreeFinished
bwPopulateTree.RunWorkerAsync()
cmbActiveUsers.Enabled = False
End Sub
Private Sub PopulateTreeStart()
Dim children As ChildList = FileManager.GetFoldersInFolder(ActiveUser.DriveService, "root")
PopulateTreeLoop(ActiveUser.Email, children)
End Sub
Private Sub PopulateTreeFinished()
lblToolStripStatus.Text = "Directory listing completed."
SaveTree()
cmbActiveUsers.Enabled = True
End Sub
Private Sub PopulateTreeLoop(nodeKey As String, ByVal childList As ChildList)
If Not childList Is Nothing Then
Dim user As GoogleUser = ActiveUser
For Each child As ChildReference In childList.Items
Dim successful As Boolean = False
If TreeView1.InvokeRequired Then
successful = TreeView1.Invoke(New m_FindAddNode(AddressOf FindAddNode), {nodeKey, child})
Else
successful = FindAddNode(nodeKey, child)
End If
Dim children As ChildList = FileManager.GetFoldersInFolder(user.DriveService, child.Id)
If Not children Is Nothing Then
PopulateTreeLoop(child.Id, children)
End If
Next
End If
End Sub
Private Function FindAddNode(nodeKey As String, child As ChildReference) As Boolean
'Returns true if successful
Try
Dim service As DriveService = ActiveUser.DriveService
Dim file As Drive.v2.Data.File = service.Files.Get(child.Id).Fetch()
Dim node() As TreeNode = TreeView1.Nodes.Find(nodeKey, True)
Dim strTitle As String
If file.FileExtension Is Nothing Then
strTitle = file.Title
Else
strTitle = If(file.Title.EndsWith(file.FileExtension), file.Title, file.Title + file.FileExtension)
End If
node(0).Nodes.Add(file.Id, strTitle)
Return True
Catch ex As Exception
Return False
End Try
End Function
And here is my FileManager class function:
Public Shared Function GetFoldersInFolder(service As DriveService, ByVal folderId As String) As ChildList
Dim request As Google.Apis.Drive.v2.ChildrenResource.ListRequest = service.Children.List(folderId)
request.Q = "mimeType='application/vnd.google-apps.folder'"
Return request.Fetch()
End Function
Sorry I had to include so much code, but I tried to include only that which is necessary. I also already have code which allows me to cache the directory structure, but decided it will be hard to implement, since I will have to be checking to make sure things haven't changed... I really just need a faster way of retrieving the directory structure. I know another way of doing this is to have the treeview only populate the subfolders once a user clicks on the parent folder, but I would like to avoid the short pause which comes from waiting for the server to respond to each request, every time the user clicks on a new folder.
I also have a function which retrieves ALL folders:
Public Shared Function GetAllFolders(service As DriveService) As FileList
Dim request As Google.Apis.Drive.v2.FilesResource.ListRequest = service.Files.List
Dim request2 As Google.Apis.Drive.v2.FilesResource.ListRequest = service.Files.List
request.Q = "mimeType='application/vnd.google-apps.folder'"
Return request.Fetch()
End Function
But I can't come up with any efficient way to parse that list to come up with a directory structure... Any ideas? I really appreciate the help. I've been working on this for days...
Your method is reasonable. Sorry it is taking a long time with large Google Drives. I certainly think that you are on the right idea in only populating the child nodes when the user attempts to expand the parent. The pause there is expected, but you can mitigate it somewhat by displaying some feedback to the user, e.g. Loading....
In this age of cloud computing, users expect some delay when loading data from a remote service. This will improve in the future as network speeds improve.

What are the VS2010 Navigate to Next/Prev function declaration hotkeys?

In the Access VB6 code editor Ctrl-Up and Ctrl-Down will jump to the next/prev function declaration.
This is quite a handy navigation tool and I can't seem to find it in VS2010.
I've done some searching on google and stackoverflow and can't seem to find any reference to it.
Does anyone know if these hotkeys exist at all in VS2010?
If they don't, how the hell can they not exist in a context aware IDE like VS2010?
Yes hot keys exist: http://www.dofactory.com/ShortCutKeys/ShortCutKeys.aspx
And to move to separate declarations:
shift+ctrl+1/shift+ctrl+2
I don't think they exist in VS2010, we work in both VS6 and 2010 and it's infuriating not to have these commands.
I'm OCD with automation these days, have made a lot of macros to help me navigate. Following is some VB macro code that will do what you want in C (and probably C++ too). You can create a macro in Visual Studio and add these lines to it. The regular expression to detect function declarations is likely not perfect but I've been using them for a week now and they've worked great for me. You can map these 2 macros to the key bindings you want, Ctrl+Up or Ctrl+Down if you like. If anyone improves the regular expression I would love to see the updated version.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Public Module NavigationMacros
Private Function IsFunctionDeclaration(ByRef LineText As String) As Boolean
If Regex.IsMatch(LineText, "^[^\s\d\W\(\)]+[^\(\)]+\s+[^\s\d\W\(\)]+\s*\([^\(\)]*\)\s*$") Then
IsFunctionDeclaration = True
Else
IsFunctionDeclaration = False
End If
End Function
Private Function GetLineText(ByRef EditPoint As EnvDTE.EditPoint) As String
EditPoint.StartOfLine()
GetLineText = EditPoint.GetText(EditPoint.LineLength)
End Function
Sub GoToPreviousFunctionDeclaration()
Dim Selection As EnvDTE.TextSelection
Dim EditPoint As EnvDTE.EditPoint
Dim LineText As String
Selection = DTE.ActiveDocument.Selection
EditPoint = Selection.TopPoint.CreateEditPoint
EditPoint.LineUp()
While IsFunctionDeclaration(GetLineText(EditPoint)) = False And Not EditPoint.AtStartOfDocument
EditPoint.LineUp()
End While
If Not EditPoint.AtEndOfDocument Then
Selection.MoveToLineAndOffset(EditPoint.Line, 1)
End If
End Sub
Sub GoToNextFunctionDeclaration()
Dim Selection As EnvDTE.TextSelection
Dim EditPoint As EnvDTE.EditPoint
Dim LineText As String
Selection = DTE.ActiveDocument.Selection
EditPoint = Selection.TopPoint.CreateEditPoint
EditPoint.LineDown()
While IsFunctionDeclaration(GetLineText(EditPoint)) = False And Not EditPoint.AtEndOfDocument
EditPoint.LineDown()
End While
If Not EditPoint.AtEndOfDocument Then
Selection.MoveToLineAndOffset(EditPoint.Line, 1)
End If
End Sub
End Module

Is there a simple way to create a custom VS action for personalised comments?

Feel free to massively re-word this question.
Basically, I'm currently stripping out a huge portion of a very large framework - this involves A LOT of commenting. So I can find all of this later I am batch commenting and then copy-pasting a marker before each block that is something like this:
//MYINITIALS_REMOVE
/*if (this code is rubbish)
{
comment it out;
}*/
I'd like to create a function so that with one button press or key combination I batch comment out selected code and automatically place my tag at the beginning. So instead of the opening comment being '//' or '/*' it is 'MYINITIALS_REMOVE//' or 'MYINITIALS_REMOVE/*'
Is this possible?
EDIT Actually thinking about it, I wouldn't even mind if every single line began with 'MYINITIALS_REMOVE//'.
I think you are looking for this:
Public Sub CStyleComment()
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.TopPoint.CreateEditPoint.Insert("//MYINITIALS_REMOV" & vbCrLf & "/*")
selection.BottomPoint.CreateEditPoint.Insert("*/")
End Sub
Maybe this version is more suitable (automatic translation):
Public Sub CStyleComment()
Dim selection As TextSelection = DTE.ActiveDocument.Selection
selection.TopPoint.CreateEditPoint.Insert("//MYINITIALS_REMOV" & vbCrLf & "/*")
selection.BottomPoint.CreateEditPoint.Insert("*/")
End Sub

Visual Studio: any one click switch between tabs and spaces indentation?

I'm member of several different teams and (of course ;) some teams prefers tabs over spaces and vice versa.
Is there any more user friendly solution then loading user profile via menu->Tools... which is 10 clicks long?
I looked at devenv.exe command line parameters if there is any for loading particular user profile to have two separate *.lnk launchers of Visual Studio, but there isn't such parameter.
Then I tried to record macro, but VS is able to record only the Tools.ImportandExportSettings command and cannot record all the steps of the following wizard.
Thx for suggestions,
Petr
There is a macro in this blog entry by James Alexander to quickly toggle between tabs and spaces within Visual Studio. Then just add a toolbar command that maps to the macro and you have your one click solution.
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
Use InsTabsOff and InsTabsOn commands from Productivity Power Tools extension.

Resources