visual-studio 为整个解决方案运行自定义工具

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1913719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 11:19:40  来源:igfitidea点击:

Run Custom Tool for entire solution

visual-studiocustomtool

提问by Will

Is there a way to 'Run Custom Tool' for an entire solution?

有没有办法为整个解决方案“运行自定义工具”?

Why? The custom tool is under development and when changes are made I need to refresh all the items that use it to make sure nothing breaks.

为什么?自定义工具正在开发中,当进行更改时,我需要刷新所有使用它的项目以确保没有任何损坏。

采纳答案by Cine

Since I needed an answer for this and had to make it myself, here is the solution for "Run Custom Tool".

由于我需要一个答案并且必须自己解决,这里是“运行自定义工具”的解决方案。

If you just need to run all your T4templates again, then since VS2012 there is Transform all T4in the Buildmenu.

如果您只需要再次运行所有T4模板,那么自 VS2012 起,Build菜单中就有Transform all T4

For VS2017 they have removed macros, so follow https://msdn.microsoft.com/en-us/library/cc138589.aspxand make a plugin with your menu item instead. E.g. Name your command RefreshAllResxFiles, and paste this file in (The default command set doesnt include the dlls for VSLangProj, so just find the appropiate package in NuGet):

对于 VS2017,他们已经删除了宏,因此请按照https://msdn.microsoft.com/en-us/library/cc138589.aspx并使用您的菜单项制作插件。例如,将您的命令命名为 RefreshAllResxFiles,并将此文件粘贴到(默认命令集不包含 VSLangProj 的 dll,因此只需在 NuGet 中找到合适的包即可):

internal sealed class RefreshAllResxFiles
{
  public const int CommandId = 0x0100;
  public static readonly Guid CommandSet = new Guid(copy the guid from guidRefreshAllResxFilesPackageCmdSet from the vsct file);
  private readonly Package _package;
  private readonly DTE2 _dte;

  /// <summary>
  /// Initializes a new instance of the <see cref="RefreshAllResxFiles"/> class.
  /// Adds our command handlers for menu (commands must exist in the command table file)
  /// </summary>
  /// <param name="package">Owner package, not null.</param>
  private RefreshAllResxFiles(Package package)
  {
     _package = package ?? throw new ArgumentNullException(nameof(package));

     var commandService = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
     if (commandService != null)
     {
        var menuCommandId = new CommandID(CommandSet, CommandId);
        var menuItem = new MenuCommand(MenuItemCallback, menuCommandId);
        commandService.AddCommand(menuItem);
     }
     _dte = ServiceProvider.GetService(typeof(DTE)) as DTE2;
  }

  public static RefreshAllResxFiles Instance { get; private set; }
  private IServiceProvider ServiceProvider => _package;

  public static void Initialize(Package package)
  {
     Instance = new RefreshAllResxFiles(package);
  }

  /// <summary>
  /// This function is the callback used to execute the command when the menu item is clicked.
  /// See the constructor to see how the menu item is associated with this function using
  /// OleMenuCommandService service and MenuCommand class.
  /// </summary>
  private void MenuItemCallback(object sender, EventArgs e)
  {
     foreach (Project project in _dte.Solution.Projects)
        IterateProjectFiles(project.ProjectItems);
  }

  private void IterateProjectFiles(ProjectItems projectProjectItems)
  {
     foreach (ProjectItem file in projectProjectItems)
     {
        var o = file.Object as VSProjectItem;
        if (o != null)
           ProcessFile(o);
        if (file.SubProject?.ProjectItems != null)
           IterateProjectFiles(file.SubProject.ProjectItems);
        if (file.ProjectItems != null)
           IterateProjectFiles(file.ProjectItems);
     }

  }

  private void ProcessFile(VSProjectItem file)
  {
     if (file.ProjectItem.Name.EndsWith(".resx"))
     {
        file.RunCustomTool();
        Log(file.ProjectItem.Name);
     }
  }
  public const string VsWindowKindOutput = "{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}";

  private void Log(string fileName)
  {
     var output = _dte.Windows.Item(VsWindowKindOutput);
     var pane = ((OutputWindow)output.Object).OutputWindowPanes.Item("Debug");
     pane.Activate();
     pane.OutputString(fileName);
     pane.OutputString(Environment.NewLine);
  }
}

And the old solution for macro:

和宏的旧解决方案:

Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports VSLangProj
Imports System.Diagnostics

Public Module RecordingModule
    Sub IterateFiles()
        Dim solution As Solution = DTE.Solution
        For Each prj As Project In solution.Projects
            IterateProjectFiles(prj.ProjectItems)
        Next
    End Sub

    Private Sub IterateProjectFiles(ByVal prjItms As ProjectItems)
        For Each file As ProjectItem In prjItms
            If file.Object IsNot Nothing AndAlso TypeOf file.Object Is VSProjectItem Then
                AddHeaderToItem(file.Object)
            End If
            If file.SubProject IsNot Nothing AndAlso file.SubProject.ProjectItems IsNot Nothing AndAlso file.SubProject.ProjectItems.Count > 0 Then
                IterateProjectFiles(file.SubProject.ProjectItems)
            End If
            If file.ProjectItems IsNot Nothing AndAlso file.ProjectItems.Count > 0 Then
                IterateProjectFiles(file.ProjectItems)
            End If
        Next
    End Sub

    Private Sub AddHeaderToItem(ByVal file As VSProjectItem)
        If file.ProjectItem.Name.EndsWith(".resx") Then
            file.RunCustomTool()
            Log(file.ProjectItem.Name)
        End If
    End Sub
    Private Sub Write(ByVal name As String, ByVal message As String)
        Dim output As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
        Dim window As OutputWindow = output.Object
        Dim pane As OutputWindowPane = window.OutputWindowPanes.Item(name)
        pane.Activate()
        pane.OutputString(message)
        pane.OutputString(Environment.NewLine)
    End Sub
    Private Sub Log(ByVal message As String, ByVal ParamArray args() As Object)
        Write("Debug", String.Format(message, args))
    End Sub

    Private Sub Log(ByVal message As String)
        Write("Debug", message)
    End Sub

End Module

回答by Rush Frisby

In Visual Studio 2010 there is a button in the icon bar of the solution navigator that will run all of the t4 templates in a solution.

在 Visual Studio 2010 中,解决方案导航器的图标栏中有一个按钮,它将运行解决方案中的所有 t4 模板。

In Visual Studio 2012 show the "Build" toolbar. There is a button in that toolbar that will run all of the t4 templates in a solution.

在 Visual Studio 2012 中显示“构建”工具栏。该工具栏中有一个按钮,可以运行解决方案中的所有 t4 模板。

回答by kellyb

You can execute all T4 templates in a solution in Visual Studio 2010. Right-click on the upper toolbar space and enable the "Build" toolbar. This will add a toolbar with the following:

您可以在 Visual Studio 2010 的解决方案中执行所有 T4 模板。右键单击上方的工具栏空间并启用“构建”工具栏。这将添加一个包含以下内容的工具栏:

  • Build Selection
  • Build Solution
  • Transform All T4 Templates
  • Cancel
  • 构建选择
  • 构建解决方案
  • 转换所有 T4 模板
  • 取消

"Transform All T4 Templates" should give you what you want.

“转换所有 T4 模板”应该给你你想要的。

回答by Scott Munro

For anyone who started using the solution provided in the other answers but is finding that running all of the templates in the solution is taking too long - and if a subset of the templates would suffice - then it is possible to run multiple templates using the following steps.

对于开始使用其他答案中提供的解决方案但发现运行解决方案中的所有模板花费的时间太长的任何人 - 如果模板的子集就足够了 - 那么可以使用以下方法运行多个模板脚步。

  1. Select the templates that you wish to run in the Solution Explorer in Visual Studio. Note that it is the actual files that you should select - not the folder that contains them.
  2. Right click on one of the selected template files and select Run Custom Toolfrom the context menu.
  1. 选择您希望在 Visual Studio 的解决方案资源管理器中运行的模板。请注意,您应该选择实际文件,而不是包含它们的文件夹
  2. 右键单击选定的模板文件之一,然后Run Custom Tool从上下文菜单中进行选择。