惊艳的Visual Studio宏

67

针对小型社区讨论,你使用哪些必要的Visual Studio宏?

我刚开始学习它们,并且想听听你们中有哪些宏是必不可少的。


36
我完全不同意关闭这个问题。这是非常有建设性和好的问题。 - David Morton
7
我同意。这是一个有用的主题,并包含了我正在寻找的答案。 - SturmUndDrang
1
在VS 2012中,宏编辑器已被移除。这是坏消息。好消息是,您可以通过创建插件,在所选语言中使用基本相同的代码。创建一个Visual Studio插件项目,其中包含您需要的样板代码。测试时,VS 2012将启动一个带有您的插件安装的单独实例。当您准备好实际部署时,请转到“My Documents\Visual Studio 2012\Addins”。在那里,对于您的项目“whatever”,请放置您的插件的“whatever.dll”,以及来自主项目目录的“whatever.AddIn”文件。 - Ryan Lundy
2
我在这里发布了如何创建插件的说明:Visual Studio 2012中宏的替代方案 - Ryan Lundy
3
是的,stackoverflow.com社区需要修改做事方式。一些最受欢迎的问题被关闭了。 - TheLegendaryCopyCoder
这应该放在Dcoumentation中。 - MSalters
14个回答

31

我在工具栏上添加了以下3个宏的按钮。每个按钮都会获取当前选择的任意文件中的文本并在Google(或MSDN,或拼写检查)中搜索它。为工具栏制作一个漂亮的图标以增加额外的样式分。

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

现在有一个拼写检查扩展,顺便说一下。 - John Gietzen

26

在输出窗口中显示构建持续时间

将以下代码放入您的EnvironmentEvents模块中。这将直接将持续时间写入到构建窗口,适用于解决方案上的任何操作(构建、重新构建、清理、部署)。

您可以更改IsBuild函数以指定需要查看此信息的操作。

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

4
我有类似的东西,但我想知道是否有一种方法可以创建一个持续的累计总数,这样我就可以跟踪我花费在编译上的时间有多少。 - Dolphin
当然可以,只需将时间跨度存储在数据库中即可。据我所知,您可以在宏中运行几乎任何代码。因此,只需编写代码以存储最新的TimeSpan,然后检索总和并显示即可。 - Ryan Lundy
有点晚了,但还是想感谢你提供的这个,正是我所需要的。另外一提:你可以使用 ow.OutputWindowPanes.Item("Build").OutputString(message) 代替 For Each - Chrono
由于某些原因,这对我不起作用,我是否需要以某种方式启用调用环境事件? - Ian Ringrose
@IanRingrose,你使用的是哪个版本的Visual Studio?宏在VS 2012中已被删除。如果你无法让宏正常工作,可以尝试创建一个插件。请参考这个答案 - Ryan Lundy
显示剩余3条评论

14

在关闭解决方案后显示启动页(但保持 Visual Studio 开启)

将以下代码放入您的 EnvironmentEvents 模块中:

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


打开解决方案后隐藏起始页

将此代码放入您的 EnvironmentEvents 模块中:

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
这两个设置将使得你的开始页面在打开一个解决方案时隐藏。当你关闭解决方案后,开始页会重新出现。

11
谁真正需要起始页? - kizzx2
2
VS 2010在启动页面上添加了“加载项目后关闭页面”选项,因此不再需要关闭宏。他们有“启动时显示页面”和“关闭解决方案后显示页面”的选项,但由于我不知道的奇怪原因,没有“关闭解决方案后显示页面”的选项,这是与“加载项目后关闭页面”相匹配的相反选项。谁需要启动页面?我用它来固定最近的项目。据我所知,在2010年,这是您可以固定最近的项目/解决方案的唯一位置。您无法固定“文件”->“最近使用的项目和解决方案”菜单中的项目,因此不适合长期使用。 - minnow

13

我经常使用以下不太为人知的快捷键:

  • Ctrl+Enter:在当前行上方插入一个空行(并将光标移到那里)
  • Ctrl+Shift+Enter:在当前行下方插入一个空行(并将光标移到那里)
  • Ctrl+Shift+V:循环浏览剪贴板环

你能向我们解释一下它们应该做什么吗? - levesque

9

大纲:将区域折叠为定义,但展开区域

你是否在那种坚持在每个代码块周围添加区域的店铺工作,以便在折叠到定义时无法看到任何代码?

你真正需要的是一个折叠到定义但展开区域的宏,就像这个:

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

将它放入常规宏模块中,并分配给热键,你的代码就回来了。

(除非...如果你与一些把区域放在方法内部的非常不道德的人一起工作,这将不幸地扩展这些方法。如果有人知道一种避免这种情况的写法,请随意编辑。)


8

插入GUID,非常适用于WiX工作,可以将其添加到菜单中作为按钮或键盘快捷方式。

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

整理解决方案中所有.cs文件的使用 - 原作者: 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

5

折叠所有节点的解决方案面板,对于大型项目尤其有用:

    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

4

如果我要将代码示例粘贴到博客文章或电子邮件中,我会使用Jeff的FormatToHtml宏。


4
我使用双显示器,我发现Sharon的布局切换宏(从1个监视器到2个监视器布局)非常有用。当您需要在输入代码时引用网页或其他程序时,请使用Ctrl-Alt-1切换到单显示器布局以查看Visual Studio窗口。完成后,使用Ctrl-Alt-2切换到双显示器布局并获取所有窗口。太棒了! http://www.invisible-city.com/sharon/2008/06/workstation-hack-visual-studio-on-2.html

那个链接已经失效了。 - videoguy

2

虽然它本身不是一个宏,但它很有用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接