如何在Visual Studio 2012中格式化所有文件?

29

在之前的Visual Studio版本中,我使用了Kevin Pilch-Bisson的脚本来格式化我的解决方案中的所有C#文件。

由于VS2012不再支持宏,因此该方法不再适用。

我该如何在VS2012中轻松格式化我的所有文档?


4
我发布这个问题是为了记录我找到的解决方案。但也许还有其他好的想法呢? - Jay Bazuzi
你能把你的答案标记为正确吗? - Danny Bullis
6个回答

28

打开工具->库包管理器->包管理器控制台,并运行以下命令。最后,所有文档将在IDE中打开。(低内存机器将在大型解决方案中遇到问题。)更改的文件将在IDE中修改,而不保存到磁盘。如果准备好了,可以全部保存,然后全部关闭。

VS2012删除了在以前版本的Visual Studio中存在的类似VB的宏语言。但是,底层的DTE接口仍然存在,并且您可以通过PowerShell,在包管理器控制台中访问它

传递给ProjectItem.Open的奇怪GUID是Constants.vsViewKindCode

通常我会将其拆分成多行,但包管理器控制台不支持行连续。

您可以在https://gist.github.com/JayBazuzi/9e0de544cdfe0c7a4358找到最新版本。

function f($projectItems) { $projectItems | ? { $_.Name.EndsWith( ".cs" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

不幸的是,当您的项目位于解决方案文件夹中时,这似乎不起作用...我对PowerShell不够熟悉,无法提出改进建议。您有什么建议吗? - Anthony
太棒了!如果$_有任何ProjectItems,它将需要进行递归迭代。你可以编写一个递归函数,或者使用闭包。如果没有其他人先处理它,我稍后会看一下。 - Jay Bazuzi
@Anthony:我已经更新为递归。告诉我你的想法。 - Jay Bazuzi
2
这里有一个小的合并请求,用于在格式化代码(“*.Designer.cs”)时排除自动生成的文件: https://gist.github.com/ubikuity/62335a46d4439b94a034 - Jonas at Software Journey

11

以下是现有脚本的更新版本,可用于处理非常大的解决方案。

它会打开每个文件,格式化它,然后保存并关闭该文件,而不是让它保持开启状态。它还会跳过 ".designer." 文件,因为这些文件通常应该被保留不变。

在最近的 Visual Studio 版本(2017年之后),请将脚本复制到 ps1 文件中,然后在“程序包管理器控制台”中运行 . C:\path\to\the.ps1 来调用它。 (在 Visual Studio 2012 和 2013 中,可以直接将其复制粘贴到“程序包管理器控制台”中。)

请注意: 将此代码粘贴到控制台中将立即打开和格式化整个解决方案中的每个 C# 文件,并保存每个修改过的文件而不进行询问。可能最好先进行分支操作...

function FormatItems($projectItems) {
    $projectItems |
    % {
        # Write-Host "    Examining item: $($_.Name)";

        if ($_.Name -and $_.Name.ToLower().EndsWith(".cs") `
            -and (-not $_.Name.ToLower().Contains(".designer."))) {

            $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}');
            $win.Activate();

            $dte.ExecuteCommand('Edit.FormatDocument');

            if (!$_.Saved) {
                Write-Host "    Saving modified file: $($_.Name)";
                $dte.ExecuteCommand('File.SaveSelectedItems');
            }

            $dte.ExecuteCommand('Window.CloseDocumentWindow');
        }

        if ($_.ProjectItems -and ($_.ProjectItems.Count -gt 0)) {
            # Write-Host "    Opening sub-items of $($_.Name)";

            FormatItems($_.ProjectItems);
        }
    };
}

$dte.Solution.Projects | % {
    Write-Host "-- Project: $($_.Name)";

    FormatItems($_.ProjectItems)
}
;

当您的解决方案的根目录由解决方案文件夹而不是项目组成时,似乎无法正常工作。 - Rudey
1
以当前的形式,无法将其复制并粘贴到VS 2017中,会产生错误。 - bbodenmiller

2
您可以使用CodeMaid,这是一个适用于VS2012的免费插件。它可以帮助您清理和重新组织代码。在使用StyleCop检查我的代码之前,我总是会先使用它。

1
虽然CodeMaid可能是一个很棒的工具,但默认情况下它做的事情比问题所要求的要多得多,应用了比Visual Studio内置代码格式化更多的清理操作。这可能是需要的,也可能不是。 - explunit

1

0
这是前两个答案的另一种变体,用户可能会发现它很有用...当然还有进一步改进和简化的空间。这不仅格式化.cs文件,还可以格式化.json.cshtml.js.css文件。
function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".cs" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".json" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".cshtml" ) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".js" ) -and (-not $_.Properties.Item("FullPath").Value.Contains("common")) -and (-not $_.Properties.Item("FullPath").Value.Contains("Content")) -and (-not $_.Properties.Item("FullPath").Value.Contains("Scripts")) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

function f($projectItems) { $projectItems | ? { $_.Name -ne $null -and $_.Name.EndsWith( ".css" ) -and (-not $_.Properties.Item("FullPath").Value.Contains("common")) -and (-not $_.Properties.Item("FullPath").Value.Contains("Content")) -and (-not $_.Properties.Item("FullPath").Value.Contains("Scripts")) } | % { $win = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}') ; $win.Activate() ; $DTE.ExecuteCommand('Edit.FormatDocument') } ; if ($projectItems) { $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

-4

前往 --> 工具 -->> 选项 -->> 文本编辑器 -->> XAML -->> 格式设置 -->> 空格 -->> 勾选每个属性单独一行!就这样


1
哎呀?我觉得你误解了我的问题。 - Jay Bazuzi

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