编辑:
GSerjo提供了正确的解决方案。我想分享一些有关如何改进它的想法(和解释)。我希望我改进的答案对遇到相同问题的其他人有用。
将VS调试器附加到进程
手动地
- 打开Windows任务管理器(
Ctrl
+Shift
+Esc
)。 - 转到选项卡
Processes
。 - 右键单击该过程。
- 选择
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);}


