如何告诉正在运行的Visual Studio 2012实例从另一个应用程序调用的VBScript中运行某个宏?

时间:2014-05-02 19:55:18

标签: visual-studio visual-studio-2012 vbscript

我在Visual Studio 2012的两个不同实例中打开了两个不同的解决方案(A和B)。

我想写两个宏 - MacroA和MacroB。应该使用解决方案A和宏B在VS实例上运行MacroA - 在VS实例上使用解决方案B运行。

以下是我想从MacroA做的事情:

  1. 启动秒表
  2. 触发当前解决方案的构建(即A)
  3. 构建完成后,停止秒表并输出已用时间
  4. 告诉其他VS实例运行MacroB
  5. 以下是我想从MacroB做的事情:

    1. 启动秒表
    2. 触发当前解决方案的构建(即B)
    3. 停止秒表并输出已用时间
    4. 请注意,我完全了解如何使用devenv(或msbuild)在命令行上构建解决方案。我明确地希望从IDE构建。

      有可能做我想做的事吗?

1 个答案:

答案 0 :(得分:0)

最后借助以下资源解决了这个问题:

这就是我所做的。

<强> 1。辅助.NET exe

以下是源代码:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;

namespace VSInstanceFinder
{
    public static class Program
    {
        [DllImport("ole32.dll")]
        public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

        [DllImport("ole32.dll")]
        public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);

        public static DTE Find(string solutionFilePath)
        {
            var numFetched = new IntPtr();
            IRunningObjectTable runningObjectTable;
            IEnumMoniker monikerEnumerator;
            var monikers = new IMoniker[1];

            GetRunningObjectTable(0, out runningObjectTable);
            runningObjectTable.EnumRunning(out monikerEnumerator);
            monikerEnumerator.Reset();

            while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
            {
                IBindCtx ctx;
                CreateBindCtx(0, out ctx);

                object runningObjectVal;
                runningObjectTable.GetObject(monikers[0], out runningObjectVal);

                var dte = runningObjectVal as DTE;
                try
                {
                    if (dte != null && dte.Solution != null && string.Equals(dte.Solution.FullName, solutionFilePath, StringComparison.OrdinalIgnoreCase))
                    {
                        return dte;
                    }
                }
                catch
                {
                }
            }

            return null;
        }

        public static OutputWindowPane GetBuildOutputPane(object o)
        {
            try
            {
                var dte = (DTE)o;
                var outputWindow = (OutputWindow)dte.Windows.Item("{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}").Object;

                for (var i = 1; i <= outputWindow.OutputWindowPanes.Count; i++)
                {
                    if (outputWindow.OutputWindowPanes.Item(i).Name.Equals("Build", StringComparison.CurrentCultureIgnoreCase))
                    {
                        return outputWindow.OutputWindowPanes.Item(i);
                    }
                }

                return outputWindow.OutputWindowPanes.Add("Build");
            }
            catch
            {
                return null;
            }
        }

        public static string GetBuildLog(object o)
        {
            try
            {
                var buildOutputPane = o as OutputWindowPane;
                if (buildOutputPane == null || buildOutputPane.TextDocument == null)
                {
                    return "";
                }
                var sel = buildOutputPane.TextDocument.Selection;
                if (sel == null)
                {
                    return "";
                }
                sel.StartOfDocument();
                sel.EndOfDocument(true);
                return sel.Text;

            }
            catch
            {
                return "";
            }
        }

        public static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                var dte = Find(args[0]);
                if (dte != null)
                {
                    Console.WriteLine(GetBuildLog(GetBuildOutputPane(dte)));
                }
            }
        }
    }
}

<强> 2。的powershell

[System.Reflection.Assembly]::LoadFile('C:\utils\VSInstanceFinder.exe')
function buildOneIDE([int]$i, [string]$ts, [string]$solution)
{
  $solutionFilePath = "$(Get-Location)\$solution.sln"
  $dte = [VSInstanceFinder.Program]::Find($solutionFilePath)
  if (!$dte)
  {
    Write-Host "$solutionFilePath does not seem to be open in any of the running Visual Studio instances"
    exit 1
  }
  $buildOutputPane = [VSInstanceFinder.Program]::GetBuildOutputPane($dte)

  $sw = New-Object System.Diagnostics.Stopwatch
  $logFileName = "c:\tmp\logs\ui.$i.$solution.$ts.log"
  $sw.Start()
  $dte.Solution.SolutionBuild.Build($true)
  $sw.Stop()
  [VSInstanceFinder.Program]::GetBuildLog($buildOutputPane) > $logFileName
  "Elapsed Total: $([int]$sw.Elapsed.TotalSeconds) seconds" >> $logFileName
  $logFile = dir $logFileName
  "$($logFile.Length)`t$($logFile.FullName)"
}
buildOneIDE 1 $(get-date -Format "yyyyMMddHHmmss") "DataSvc"

我需要的是什么。