使用Process.Start()启动的项目无法进行调试。

14

我在同一个解决方案中有两个C# WinForm项目,我们称它们为A和B。 项目A通过以下调用启动了进程B:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Task.EXEFilename;
psi.WorkingDirectory = Path.GetDirectoryName(Data.EXEFilename);
Process.Start(psi);

进程B已经正确启动。我想在调试A的同时调试进程B。我认为在B中设置断点就足够了,但是断点从未命中。我已经验证启动的进程位于B的bin/debug文件夹中。在这种情况下,我不应该使用“附加到进程”来切换从A到B的调试吗?


你的调试器已经附加到进程A上,因此无法调试进程B。你需要附加一个单独的调试器到进程B上才能进行调试。 - ThaMe90
1
使用“调试”->“附加到进程”来完成此操作。 - Kamil Budziewski
如果是WinForm,你不能只将其作为一个新窗体打开,而不是调用它作为一个进程吗? - Andrius Naruševičius
你正在运行编译后的Exe文件作为进程B,我不确定你是否能够像你试图做的那样进行调试。 - Sayse
5个回答

34

在第二个项目中,检查其命令行参数,如果看到像--debug这样的内容作为第一个参数传递进来,第二个程序自己启动调试器。

private static void Main(string[] args)
{
    //If no debugger is attached and the argument --debug was passed launch the debugger
    if (args.Length == 1 && args[0] == "--debug" && Debugger.IsAttached == false)
        Debugger.Launch();

    //(snip) the rest of your program

}

当您这样做时,将出现一个对话框窗口,让您选择是打开新的Visual Studio副本还是使用已经打开的副本。

image


您也可以将子进程放在Image File Execution Options注册表键中


仅凭这个,您可能还可以使用预处理指令,如:#if DEBUG Debugger.Launch(); #endif - Carlos

7
看起来你想让Visual Studio在调试期间自动附加到任何创建的子进程。像windbg这样的其他调试器具有此行为,但不幸的是,Visual Studio没有。有一个用户反馈正在跟踪此请求。短期内,最好的选择是在生成子进程的点上设置断点,并手动附加调试器。以下是链接:http://connect.microsoft.com/VisualStudio/feedback/details/772727/when-a-child-process-is-spawned-debugger-does-not-attach-to-it
var proc = Process.Start(psi);
Debugger.Break();  

好的回答!注意:Scott的回答也处理了当您需要从一开始就调试进程的情况(这正是我所需要的)。 - Lucio Paiva

1

尝试从程序B获取进程ID,类似于:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Task.EXEFilename;
psi.WorkingDirectory = Path.GetDirectoryName(Data.EXEFilename);
var proc = Process.Start(psi);

Debug.WriteLine(proc.Id);

然后在另一个 Visual Studio 实例中加载您的项目,使用“调试”>“附加到进程”来附加到程序 B。


该项目很可能在同一个解决方案中,因此可以从同一个Visual Studio中附加它。(这并不意味着这不会让人感到困惑...) - ANeves

1

这里是一个我被展示的解决方案...

  1. 在您想要调试的项目B中添加一个消息框。

    MessageBox.Show("pause");

  2. 在项目B中的消息框代码后面的某个位置添加断点。

  3. 运行代码,直到消息框出现。 message box image

  4. 选择 调试 > 附加到进程

  5. 在弹出的窗口中,选择您正在执行并希望逐步执行的项目B的名称。单击“确定”。

  6. 单击由消息框代码创建的消息框上的“确定”按钮。 message box image

现在,您应该位于您在项目B中的消息框代码后面放置的断点处!


0
您也可以尝试不直接启动B进程。右键单击解决方案,选择属性|常规属性|启动项。将Process A和Process B都设置为启动。这样就可以模拟Process B被Process A启动(在A的源代码中注释掉A启动B的部分)。现在,您可以测试A和B之间的进程间通信,就好像B是由A启动的一样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接