24

是否可以为解决方案中的所有文件或特定文件运行自动格式化代码,例如 Visual Studio 中的 (Ctrl+K, Ctrl+D) 格式化,但可以从命令行运行?或者也从命令行使用 Resharper 的清理来处理解决方案文件?

4

5 回答 5

12

创建您自己的工具。您可以使用EnvDTE,EnvDTE80创建 Visual Studio 项目并动态加载要格式化的文件。完成后删除 Visual Studio 项目。您可以指定在格式化时不显示 Visual Studio 窗口。如果你有兴趣让我知道我可以给你一些代码来完成这项工作。

更新:我正在复制我拥有的代码。我用它来格式化 *.js 文件。我删除了一些您不需要的代码。随意问它是否不起作用。

    //You need to make a reference to two dlls:
    envdte
    envdte80



    void FormatFiles(List<FileInfo> files)
    {       
        //If it throws exeption you may want to retry couple more times
        EnvDTE.Solution soln = System.Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.Solution.11.0")) as EnvDTE.Solution;
        //try this if you have Visual Studio 2010
        //EnvDTE.Solution soln = System.Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.Solution.10.0")) as EnvDTE.Solution;
        soln.DTE.MainWindow.Visible = false;
        EnvDTE80.Solution2 soln2 = soln as EnvDTE80.Solution2;
        //Creating Visual Studio project
        string csTemplatePath = soln2.GetProjectTemplate("ConsoleApplication.zip", "CSharp");
        soln.AddFromTemplate(csTemplatePath, tempPath, "FormattingFiles", false);
        //If it throws exeption you may want to retry couple more times
        Project project = soln.Projects.Item(1);

        foreach (FileInfo file in files)
        {
            ProjectItem addedItem;
            bool existingFile = false;
            int _try = 0;
            while (true)
            {            
                try
                {
                    string fileName = file.Name;
                    _try++;
                    if (existingFile)
                    {
                        fileName = file.Name.Substring(0, (file.Name.Length - file.Extension.Length) - 1);
                        fileName = fileName + "_" + _try + file.Extension;
                    }
                    addedItem = project.ProjectItems.AddFromTemplate(file.FullName, fileName);
                    existingFile = false;
                    break;
                }
                catch(Exception ex)
                {
                    if (ex.Message.Contains(file.Name) && ex.Message.Contains("already a linked file"))
                    {
                        existingFile = true;
                    }
                }
            }
            while (true)
            {
                //sometimes formatting file might throw an exception. Thats why I am using loop.
                //usually first time will work
                try
                {
                    addedItem.Open(Constants.vsViewKindCode);
                    addedItem.Document.Activate();
                    addedItem.Document.DTE.ExecuteCommand("Edit.FormatDocument");
                    addedItem.SaveAs(file.FullName);
                    break;
                }
                catch
                {
                    //repeat
                }
            }
        }
        try
        {
            soln.Close();
            soln2.Close();
            soln = null;
            soln2 = null;
        }
        catch
        {
            //for some reason throws exception. Not all the times.
            //if this doesn't closes the solution CleanUp() will take care of this thing
        }
        finally
        {
            CleanUp();
        }
    }   

    void CleanUp()
    {
        List<System.Diagnostics.Process> visualStudioProcesses = System.Diagnostics.Process.GetProcesses().Where(p => p.ProcessName.Contains("devenv")).ToList();
        foreach (System.Diagnostics.Process process in visualStudioProcesses)
        {
            if (process.MainWindowTitle == "")
            {
                process.Kill();
                break;
            }
        }
        tempPath = System.IO.Path.GetTempPath();
        tempPath = tempPath + "\\FormattingFiles";
        new DirectoryInfo(tempPath).Delete(true);
    } 

我希望这有帮助。

于 2013-03-22T22:43:44.480 回答
5

作为 Dilshod 帖子的后续,如果您只是想格式化单个文件,这里有一种不需要临时路径的方法:

static void FormatFile(string file)
{
    EnvDTE.Solution soln = System.Activator.CreateInstance(
        Type.GetTypeFromProgID("VisualStudio.Solution.10.0")) as EnvDTE.Solution;

    soln.DTE.ItemOperations.OpenFile(file);

    TextSelection selection = soln.DTE.ActiveDocument.Selection as TextSelection;
    selection.SelectAll();
    selection.SmartFormat();

    soln.DTE.ActiveDocument.Save();
}

请注意,“文件”很可能需要在磁盘上具有完整路径。相对路径似乎不起作用(尽管我没有那么努力)。

于 2013-04-19T18:19:47.710 回答
5

要格式化 net core c# 源代码,请使用https://github.com/dotnet/format

根据项目自述文件安装该工具。

我需要格式化一些从 Razor 模板生成的代码文件。我在输出文件夹的根目录中创建了一个 shell .CSProj 文件,使用dotnet new console它为您提供了这个基本文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <RootNamespace>dotnet_format</RootNamespace>
  </PropertyGroup>

</Project>

然后dotnet format从该文件夹中的 VS 命令提示符运行。它将递归到子目录并格式化它找到的所有内容。要格式化特定文件,您可以使用--files开关提供文件名列表。

于 2019-08-05T10:44:32.997 回答
2

使用 .NET 团队的 CodeFormatter

  1. 安装MSBuild 工具 2015
  2. 下载CodeFormatter 1.0.0-alpha6
  3. 添加CodeFormatter.csproj到项目的根目录:

CodeFormatter.csproj

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Compile Include="**\*.cs" />
  </ItemGroup>
  <Target Name="Compile">
    <Csc Sources="@(Compile)"/>
  </Target>
</Project>

然后从命令行运行它。

> codeformatter.exe CodeFormatter.csproj /nocopyright

结果:您的所有项目的 C# 文件现在都符合大多数 .NET Foundation编码指南

评论

  • 安装 MSBuild Tools 2015 意味着我们不需要 Visual Studio。
  • 递归地添加CodeFormatter.csproj到根目录包括所有 C# 文件,这意味着上面的内容适用于基于 project.json 和 *.xproj 的设置。

也可以看看

http://bigfontblog.azurewebsites.net/autoformat/

于 2017-01-14T02:28:33.513 回答
1

Visual Studio 不可能,但有命令行实用程序:http ://astyle.sourceforge.net/astyle.html

于 2013-03-22T22:08:37.040 回答