栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将C#中的调试器附加到另一个进程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将C#中的调试器附加到另一个进程

编辑:

GSerjo
提供了正确的解决方案。我想分享一些有关如何改进它的想法(和解释)。我希望我改进的答案对遇到相同问题的其他人有用。


将VS调试器附加到进程

手动地

  1. 打开Windows任务管理器(
    Ctrl
    +
    Shift
    +
    Esc
    )。
  2. 转到选项卡
    Processes
  3. 右键单击该过程。
  4. 选择
    Debug

或者,在Visual Studio中,选择

Debug > Attach to Process...

结果将因您是否有权访问源代码而异。

使用C#自动

一个 值得注意的问题: 下面的代码是在这个意义上脆弱的某些价值观,如Visual
Studio的版本号,是硬编码。如果您打算分发程序,请记住这一点。

首先,在您的项目中添加对EnvDTE的引用(在解决方案资源管理器中的references文件夹上单击鼠标右键,添加引用)。在下面的代码中,我只会显示不寻常的using指令;正常的诸如

usingSystem
被省略。

由于您正在与COM交互,因此需要确保使用来装饰您的

Main
方法(应用程序的入口点)
STAThreadAttribute

然后,您需要定义

IOleMessageFilter
接口,该接口将允许您与已定义的COM方法进行交互(请注意
ComimportAttribute
)。我们需要访问消息过滤器,以便我们可以重试Visual
Studio COM组件是否阻止了我们的调用之一。

using System.Runtime.InteropServices;[Comimport, Guid("00000016-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]public interface IOleMessageFilter{    [PreserveSig]    int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);    [PreserveSig]    int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);    [PreserveSig]    int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);}

现在,我们需要实现此接口以便处理传入消息:

public class MessageFilter : IOleMessageFilter{    private const int Handled = 0, RetryAllowed = 2, Retry = 99, Cancel = -1, WaitAndDispatch = 2;    int IOleMessageFilter.HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo)    {        return Handled;    }    int IOleMessageFilter.RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType)    {        return dwRejectType == RetryAllowed ? Retry : Cancel;    }    int IOleMessageFilter.MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType)    {        return WaitAndDispatch;    }    public static void Register()    {        CoRegisterMessageFilter(new MessageFilter());    }    public static void Revoke()    {        CoRegisterMessageFilter(null);    }    private static void CoRegisterMessageFilter(IOleMessageFilter newFilter)    {        IOleMessageFilter oldFilter;        CoRegisterMessageFilter(newFilter, out oldFilter);    }    [Dllimport("Ole32.dll")]    private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, out IOleMessageFilter oldFilter);}

为了更好的可读性,我将返回值定义为常量,并对整个事情进行了一些重构,以消除MSDN示例中的某些重复项,因此希望您能对它有所解释。

extern intCoRegisterMessageFilter
是我们与非托管消息过滤器代码的连接-
您可以在MSDN上的extern关键字上进行阅读。

现在剩下的就是一些说明用法的代码:

using System.Runtime.InteropServices;using EnvDTE;[STAThread]public static void Main(){    MessageFilter.Register();    var process = GetProcess(7532);    if (process != null)    {        process.Attach();        Console.WriteLine("Attached to {0}", process.Name);    }    MessageFilter.Revoke();    Console.ReadLine();}private static Process GetProcess(int processID){    var dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE.10.0");    var processes = dte.Debugger.LocalProcesses.OfType<Process>();    return processes.SingleOrDefault(x => x.ProcessID == processID);}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/575937.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号