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

我希望能够自动附加调试器,例如:System.Diagnostics.Debugger.Launch(),而不是将当前进程附加

到另一个命名进程。我有一个进程名称和PID来标识另一个进程。

这可能吗?

回答:

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


将VS调试器附加到进程

回答:

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

或者,在Visual Studio中,选择Debug > Attach to Process...

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

回答:

一个 下面的代码是在这个意义上脆弱的某些价值观,如Visual

Studio的版本号,是硬编码。如果您打算分发程序,请记住这一点。

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

System被省略。

由于您正在与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 int

CoRegisterMessageFilter是我们与非托管消息过滤器代码的连接-

您可以在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);

}

以上是 将C#中的调试器附加到另一个进程 的全部内容, 来源链接: utcz.com/qa/428279.html

回到顶部