C#AttachingtheDebuggertoAnotherProcess我希望能够自动附加调试器,例如:System.Diagnostics.Debugger.Launch(),除了当前进程到另一个命名进程。我有一个进程名称和PID来标识其他进程。是否可以?编辑:GSerjo提供了正确的解决方案。我想分享一些关于如何改进它(并解释它)的想法。我希望我改进的答案对其他有同样问题的人有用。将VS调试器手动附加到进程打开Windows任务管理器(Ctrl+Shift+Esc)。转到选项卡进程。右击进程。选择调试。或者,在VisualStudio中,选择“调试”>“附加到进程...”。结果将取决于您是否有权访问源代码。自动使用C#注意:以下代码是脆弱的,因为某些值(例如VisualStudio版本号)是硬编码的。如果您打算分发您的计划,请记住这一点。首先,在您的项目中添加对EnvDTE的引用(右键单击解决方案资源管理器中的引用文件夹,添加引用)。在下面的代码中,我只会展示不常见的using指令;省略了使用System的常规方法。由于您正在与COM交互,因此需要确保Main方法(应用程序的入口点)已使用STAThreadAttribute修饰。然后,您需要定义IOleMessageFilter接口,它允许您与定义的COM方法交互(注意ComImportAttribute。)我们需要访问消息过滤器,以便在VisualStudioCOM组件阻止其中一个调用时重试。使用System.Runtime.InteropServices;[ComImport,Guid("00000016-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]publicinterfaceIOleMessageFilter{[PreserveSig]intHandleInComingCall(intdwCallType,IntPtrhTaskCaller,intdwTickCount,IntfaceInfo);linter[PreserveSig]intRetryRejectedCall(IntPtrhTaskCallee,intdwTickCount,intdwRejectType);[PreserveSig]intMessagePending(IntPtrhTaskCallee,intdwTickCount,intdwPendingType);现在,我们需要实际这个接口以处理传入的消息:publicclassMessageFilter:IOleMessageFilter{privateconstintHandled=0,RetryAllowed=2,Retry=99,Cancel=-1,WaitAndDispatch=2;intIOleMessageFilter.HandleInComingCall(intdwCallType,IntPtrhTaskCaller,intdwTickCount,IntPtrlpInterfaceInfo){返回处理;}intIOleMessageFilter.RetryRejectedCall(IntPtrhTaskCallee,intdwTickCount,intdwRejectType){返回dwRejectType==RetryAllowed?重试:取消;}intIOleMessageFilter.MessagePending(IntPtrhTaskCallee,intdwTickCount,intdwPendingType){returnWaitAndDispatch;}publicstaticvoidRegister(){CoRegisterMessageFilter(newMessageFilter());}publicstaticvoidRevoke(){CoRegisterMessageFilter(private);CoRegisterMessageFilter(IOleMessageFilternewFilter){IOleMessageFilteroldFilter;CoRegisterMessageFilter(newFilter,outoldFilter);}[DllImport("Ole32.dll")]privatestaticexternintCoRegisterMessageFilter(IOleMessageFilternewFilter,outIOleMessageFilteroldFilter);我将返回值确定为更好的可读性,并重构整个事情以删除MSDN示例中的一些重复,所以我希望你会发现它是不言自明的externintCoRegisterMessageFilter是我们与非托管消息过滤器代码的连接-您可以在MSDN上找到有关extern关键字的阅读。现在减下的就是一些说明使用方法的代码:usingSystem.Runtime.InteropServices;使用EnvDTE;[STAThread]publicstaticvoidMain(){MessageFilter.Register();var进程=GetProcess(7532);如果(过程!=null){process.Attach();Console.WriteLine("附加到{0}",process.Name);}MessageFilter.Revoke();控制台.ReadLine();}privatestaticProcessGetProcess(intprocessID){vardte=(DTE)Marshal.GetActiveObject("VisualStudio.DTE.10.0");varprocesses=dte.Debugger.LocalProcesses.OfType();返回processes.SingleOrDefault(x=>x.ProcessID==processID);}看一下这个usingSystem;使用System.Collections.Generic;使用System.Linq;使用System.Runtime.InteropServices;使用EnvDTE;使用NUnit.Framework;namespaceUnitTests{[TestFixture]publicclassForTest{[STAThread][Test]publicvoidTest(){vardte=(DTE)Marshal.GetActiveObject("VisualStudio.DTE.10.0");MessageFilter.Register();IEnumerableprocesses=dte.Debugger.LocalProcesses.OfType();变量过程ess=processes.SingleOrDefault(x=>x.ProcessID==6152);如果(过程!=null){process.Attach();}}}publicclassMessageFilter:IOleMessageFilter{////包含IOleMessageFilter的类//线程错误处理函数。//启动过滤器。////IOleMessageFilter函数。//处理传入的线程请求。#regionIOleMessageFilterMembersintIOleMessageFilter.HandleInComingCall(intdwCallType,IntPtrhTaskCaller,intdwTickCount,IntPtrlpInterfaceInfo){//返回标志SERVERCALL_ISHANDLED。返回0;}//线程调用被拒绝,所以再试一次。intIOleMessageFilter.RetryRejectedCall(IntPtrhTaskCallee,intdwTickCount,intdwRejectType){if(dwRejectType==2)//flag=SERVERCALL_RETRYLATER.{//如果返回>=0&//<100,则立即重试线程调用。返回99;}//太忙了;取消通话。返回-1;}intIOleMessageFilter.MessagePending(IntPtrhTaskCallee,intdwTickCount,intdwPendingType){//返回e标记PENDINGMSG_WAITDEFPROCESS。返回2;}#endregionpublicstaticvoidRegister(){IOleMessageFilternewFilter=newMessageFilter();IOleMessageFilteroldFilter=null;CoRegisterMessageFilter(newFilter,outoldFilter);}//完成过滤器,关闭它。publicstaticvoidRevoke(){IOleMessageFilteroldFilter=null;CoRegisterMessageFilter(null,outoldFilter);}//实现IOleMessageFilter接口。[DllImport("Ole32.dll")]privatestaticexternintCoRegisterMessageFilter(IOleMessageFilternewFilter,outIOleMessageFilteroldFilter);}[ComImport,Guid("00000016-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]内部接口IOleMessageFilter{[PreserveSig]intHandleInComingCall(intdwCallType,IntPtrhTaskCaller,intdwTickCountlp,InInterfaceInfo);[PreserveSig]intRetryRejectedCall(IntPtrhTaskCallee,intdwTickCount,intdwRejectType);[PreserveSig]intMessagePending(IntPtrhTaskCallee,intdwTickCount,intdwPendingType);}}更简单的方法publicstaticvoidAttach(DTE2dte){varprocesses=dte.Debugger.LocalProcesses;foreach(varprocinprocesses.Cast().Where(proc=>proc.Name.IndexOf("YourProcess.exe")!=-1))proc.Attach();}内部静态DTE2GetCurrent(){vardte2=(DTE2)Marshal.GetActiveObject("VisualStudio.DTE.12.0");//对于VisualStudio2013返回dte2;}用法:附加(GetCurrent());一种选择是运行;vsjitdebugger.exe-pProcessId您可以使用Process.Start在c#应用程序中执行此操作。以上就是C#学习教程的全部内容:将C#中的调试器附加到另一个进程。代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
