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

Visual studio 为整个解决方案运行自定义工具,visual-studio,customtool,Visual Studio,Customtool,是否有一种方法可以为整个解决方案“运行自定义工具” 为什么??自定义工具正在开发中,当进行更改时,我需要刷新所有使用它的项目,以确保没有任何东西损坏。由于我需要对此问题的答案,并且必须自己制作,因此这里是“运行自定义工具”的解决方案 如果您只需要再次运行所有的T4模板,那么自VS2012以来,“构建”菜单中就有“转换所有T4” 对于VS2017,他们已经删除了宏,所以请按照下面的说明使用菜单项制作插件。例如,将您的命令命名为RefreshAllResxFiles,并将此文件粘贴到中(默认命令集不

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


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

由于我需要对此问题的答案,并且必须自己制作,因此这里是“运行自定义工具”的解决方案

如果您只需要再次运行所有的T4模板,那么自VS2012以来,“构建”菜单中就有“转换所有T4”

对于VS2017,他们已经删除了宏,所以请按照下面的说明使用菜单项制作插件。例如,将您的命令命名为RefreshAllResxFiles,并将此文件粘贴到中(默认命令集不包括VSLangProj的DLL,因此只需在NuGet中找到相应的包即可):


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


在Visual Studio 2012中,显示“生成”工具栏。该工具栏中有一个按钮,用于运行解决方案中的所有t4模板。

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

  • 构建选择
  • 构建解决方案
  • 转换所有T4模板
  • 取消

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

对于开始使用其他答案中提供的解决方案,但发现运行解决方案中的所有模板花费的时间太长的人,如果模板的一个子集就足够了,则可以使用以下步骤运行多个模板

  • 选择希望在Visual Studio的解决方案资源管理器中运行的模板。请注意,您应该选择的是实际文件,而不是包含这些文件的文件夹
  • 右键单击其中一个选定的模板文件,然后从关联菜单中选择“运行自定义工具”

  • 你说的是持续集成吗?不是CI。我们使用几个t4文件生成代码,最好运行exe,在我们构建时转换所有这些文件。这是宏的代码。您可以在宏IDE中的“工具>宏>宏IDE”下添加此代码。从VS2017 4.7.02558开始,“转换所有T4模板”将返回到生成中menu@smirkingman:Transform all T4 templates(转换所有T4模板)返回到Build(生成)菜单中,但它似乎至少部分失效。它没有在dotnetcore v2.0项目上运行。它仍然存在于Visual Studio 2015中。我确认它在VS2017 Enterprise v15.6.2中可用,至少在菜单和工具栏中也可用
    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