为整个解决方案运行自定义工具 [英] Run Custom Tool for entire solution

查看:102
本文介绍了为整个解决方案运行自定义工具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种方法可以为整个解决方案运行自定义工具"?

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.

推荐答案

由于我需要对此做出回答,而且必须自己解决,因此这里是运行自定义工具"的解决方案.

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

如果您只需要再次运行所有 T4 模板,则自VS2012起, Build 菜单中的转换所有T4 .

If you just need to run all your T4 templates again, then since VS2012 there is Transform all T4 in the Build menu.

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

For VS2017 they have removed macros, so follow https://msdn.microsoft.com/en-us/library/cc138589.aspx and 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):

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);
  }
}

还有宏的旧解决方案:

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

这篇关于为整个解决方案运行自定义工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆