ソリューション全体に対して「カスタム ツールを実行する」方法はありますか?
なんで?カスタム ツールは開発中であり、変更が加えられた場合は、それを使用するすべてのアイテムを更新して、問題がないことを確認する必要があります。
ソリューション全体に対して「カスタム ツールを実行する」方法はありますか?
なんで?カスタム ツールは開発中であり、変更が加えられた場合は、それを使用するすべてのアイテムを更新して、問題がないことを確認する必要があります。
Visual Studio 2010 では、ソリューション ナビゲーターのアイコン バーに、ソリューション内のすべての t4 テンプレートを実行するボタンがあります。
Visual Studio 2012 では、[ビルド] ツールバーを表示します。そのツールバーには、ソリューション内のすべての t4 テンプレートを実行するボタンがあります。
これに対する答えが必要で、自分で作成する必要があったため、「Run Custom Tool」の解決策を次に示します。
すべてのT4テンプレートを再度実行する必要がある場合は、VS2012 以降、[ビルド] メニューに [すべての T4 を変換] があります。
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);
}
}
そしてマクロの古い解決策:
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
他の回答で提供されているソリューションの使用を開始したが、ソリューション内のすべてのテンプレートの実行に時間がかかりすぎていることに気付いた場合、およびテンプレートのサブセットで十分な場合は、次を使用して複数のテンプレートを実行できます。ステップ。
Run Custom Tool
、コンテキスト メニューから選択します。