VCmd script to compile current file and build a project

2018-04-08 09:27:12 Coding C# Visual Studio

Useful for CUDA development, since VS somehow does not monitor the changes in CU files.

using EnvDTE;
using EnvDTE80;

public class Runner
{
    private const string PaneName = "VCmd";
    private DTE2 _dte;
    private int _step = 0;
    private OutputWindowPane _pane = null;
    private BuildEvents _buildEvents;

    public Runner(DTE2 dte)
    {
        _dte = dte;
        _buildEvents = dte.Events.BuildEvents;

        var panes = ((OutputWindow)_dte.Windows.Item(Constants.vsWindowKindOutput).Object).OutputWindowPanes;
        foreach (OutputWindowPane pane in panes)
        {
            if (pane.Name == PaneName)
            {
                _pane = pane;
                break;
            }
        }
        if (_pane == null)
        {
            _pane = panes.Add(PaneName);
        }
    }

    private void Log(string msg)
    {
        _pane.OutputString(String.Format("[{0:HH:mm:ss.fff}] {1}{2}", DateTime.Now, msg, Environment.NewLine));
    }

    public void Start()
    {
        Log("Script start..");
        _buildEvents.OnBuildDone += BuildEvents_OnBuildDone;
        _dte.ExecuteCommand("Build.Compile");
    }

    private void Build(string name)
    {
        var sol = _dte.Solution;
        foreach (Project proj in sol.Projects)
        {
            if (proj.Name == name)
            {
                sol.SolutionBuild.BuildProject(_dte.Solution.SolutionBuild.ActiveConfiguration.Name, proj.UniqueName, true);
                break;
            }
        }
    }

    private void BuildEvents_OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
    {
        Log(String.Format("Script step {0}", _step));
        switch (_step)
        {
            case 0:
                _step = 1;
                Build("DependingProject");
                break;
            case 1:
                _dte.Events.BuildEvents.OnBuildDone -= BuildEvents_OnBuildDone;
                break;
        }
    }
}

public class C : VisualCommanderExt.ICommand
{
    private Runner _runner;
    public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        _runner = new Runner(DTE);
        _runner.Start();
    }
}