运行Visual Studio 2010实例并以编程方式附加到进程? [英] Getting running Visual Studio 2010 instances and programmatically attaching to a process?

查看:205
本文介绍了运行Visual Studio 2010实例并以编程方式附加到进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WinForms应用程序(.net 3.5),它显示一个进程列表。



我希望能够附加到其中一个进程。我有多个Visual Studio 2010实例运行,我想创建一个列表/下拉列表,我选择其中一个实例,然后附加调试器。



获取VS2010实例不应该太硬,但是我不知道如何调用附加到进程命令。我想避免SendKeys-Type解决方案,所以我只是想知道有没有办法这样做?



编辑:澄清:我想要使用特定的运行的VS2010调试外部应用程序。

解决方案

一种方法是使用EnvDTE,它是COM自动化界面对于Visual Studio:



http://msdn.microsoft.com/en-us/library/envdte(VS.100).aspx



你可以在运行对象表(ROT)中通过钓鱼来获取运行Visual Studio实例的自动化界面。一旦你有一个接口的实例,你可以自动选择一个Visual Studio实例附加到你想要的进程。



下面是一个基本的例子,如何做这个。您将需要向EnvDTE添加对项目的引用。此程序集位于机器上的以下位置:



C:\程序文件(x86)\ Microsoft Visual Studio 10.0 \Common7 \IDE \PublicAssemblies\EnvDTE.dll



已更新



更新以给出通过进程ID获取Visual Studio实例自动化界面的示例。

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

命名空间VS2010EnvDte
{
内部类程序
{
[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);

private static void Main()
{
// VS实例的ProcessId - 硬编码。
int visualStudioProcessId = 5520;

_DTE visualStudioInstance;

if(TryGetVSInstance(visualStudioProcessId,out visualStudioInstance))
{
进程processToAttachTo = null;

//找到您希望VS实例附加到的进程...
foreach(visualStudioInstance.Debugger.LocalProcesses中的进程)
{
if( process.Name == @C:\Users\chibacity\AppData\Local\Google\Chrome\Application\chrome.exe)
{
processToAttachTo = process;
break;
}
}

//附加到进程。
if(processToAttachTo!= null)
{
processToAttachTo.Attach();
}
}
}

private static bool TryGetVSInstance(int processId,out _DTE instance)
{
IntPtr numFetched = IntPtr.Zero ;
IRunningObjectTable runningObjectTable;
IEnumMoniker monikerEnumerator;
IMoniker [] 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);

string runningObjectName;
monikers [0] .GetDisplayName(ctx,null,out runningObjectName);

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

if(runningObjectVal为_DTE&& runObjectName.StartsWith(!VisualStudio))
{
int currentProcessId = int.Parse(runningObjectName.Split(' )[1]);

if(currentProcessId == processId)
{
instance =(_DTE)runningObjectVal;
返回true;
}
}
}

instance = null;
返回false;
}
}
}


I have a WinForms Application (.net 3.5) which displays a list of processes.

I would like to be able to attach to one of those processes. I have multiple Visual Studio 2010 instances running and I would like to create a List/Dropdown where I select one of those instances and then attach the Debugger to it.

Getting the VS2010 instances shouldn't be too hard, but I have no idea how to invoke the "attach to process" command. I want to avoid SendKeys-Type solutions, so I just wonder if there is some way to do that?

edit: To clarify: I want to use a specific running VS2010 to debug an external application.

解决方案

One approach is to use EnvDTE which is the COM automation interface for Visual Studio:

http://msdn.microsoft.com/en-us/library/envdte(VS.100).aspx

You can get at automation interfaces for running instances of Visual Studio by fishing around in the Running Objects Table (ROT). Once you have an instance of the interface you can then automate a selected instance of Visual Studio to attach to a process you desire.

Below is a basic example of how to do this. You will need to add a reference to your project to EnvDTE. This assembly is at the following location on my machine:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll

Updated

Updated to give example of getting Visual Studio instance automation interface by process ID.

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

namespace VS2010EnvDte
{
internal 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);

    private static void Main()
    {
        //ProcessId of the VS instance - hard-coded here.
        int visualStudioProcessId = 5520;

        _DTE visualStudioInstance;

        if (TryGetVSInstance(visualStudioProcessId, out visualStudioInstance))
        {
            Process processToAttachTo = null;

            //Find the process you want the VS instance to attach to...
            foreach (Process process in visualStudioInstance.Debugger.LocalProcesses)
            {
                if (process.Name == @"C:\Users\chibacity\AppData\Local\Google\Chrome\Application\chrome.exe")
                {
                    processToAttachTo = process;
                    break;
                }
            }

            //Attach to the process.
            if (processToAttachTo != null)
            {
                processToAttachTo.Attach();
            }
        }
    }

    private static bool TryGetVSInstance(int processId, out _DTE instance)
    {
        IntPtr numFetched = IntPtr.Zero;
        IRunningObjectTable runningObjectTable;
        IEnumMoniker monikerEnumerator;
        IMoniker[] 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);

            string runningObjectName;
            monikers[0].GetDisplayName(ctx, null, out runningObjectName);

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

            if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio"))
            {
                int currentProcessId = int.Parse(runningObjectName.Split(':')[1]);

                if (currentProcessId == processId)
                {
                    instance = (_DTE)runningObjectVal;
                    return true;
                }
            }
        }

        instance = null;
        return false;
    }
}
}

这篇关于运行Visual Studio 2010实例并以编程方式附加到进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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