如何将 Visual Studio 附加到尚未启动的进程?
Posted
技术标签:
【中文标题】如何将 Visual Studio 附加到尚未启动的进程?【英文标题】:How do I attach Visual Studio to a process that is not started yet? 【发布时间】:2011-12-31 08:13:39 【问题描述】:由于某些原因(从 Excel 2010 模板项目创建的 Excel 文件),我的 .NET 程序无法从 Visual Studio 运行,我需要为此调试启动事件。
如果我想调试程序初始化后发生的事件,那没有问题。我从资源管理器运行程序,将进程附加到 Visual Studio 并在代码中添加一些断点。但是在这里,我需要在启动事件上设置断点。我需要能够将进程附加到 Visual Studio,而不是依赖于 PID,而是依赖于特定的进程名称或任何其他可行的解决方案。
当然,在我的启动事件中添加 Thread.Sleep(1000)
以便我有时间在 Visual Studio 中附加该进程是不可能的!
【问题讨论】:
【参考方案1】:其实你可以;你不依附它,你开始它。在项目的属性中,在“调试”选项卡上,在“命令”文本框中指定要附加到的程序的路径。
您还可以在“命令参数”框中为程序输入任何命令行参数:
确保“附加”设置为“否”。
【讨论】:
很好的解决方案,但请注意,在这种情况下按 F5 不起作用。而是右键单击相关项目,然后从上下文菜单中单击“调试 > 启动新实例”。 为了让 F5 工作,您的项目必须是解决方案中的起始项目。为此,请在解决方案资源管理器中右键单击项目并选择“设置为启动项目”。 此外,如果您的程序有一些外部依赖项,您还需要更改“工作目录”。 可能需要勾选"Enable native code debugging"(项目属性→Debug→Enable Debuggers) . 您如何为包含 40 个项目的整个解决方案做到这一点?【参考方案2】:如果您拥有 Visual Studio 2017-2022,请按照以下步骤操作:
-
文件 > 打开 > 项目/解决方案
选择您的 .exe
调试 > 开始调试
如果 Visual Studio 没有自动找到调试符号,则必须告诉它在哪里。
这比其他建议更容易:您不必弄乱项目属性,也不需要扩展。
【讨论】:
5 秒内快速轻松地完成,我喜欢它。谢谢 我的 exe 已启动,但无法设置断点。我该怎么办?【参考方案3】:我在一个外部生成的进程中调试了一个 C++ 插件,该进程在启动时抛出异常而崩溃,这对我来说非常有效:
添加免费的Reattach Extension for Visual Studio。要求它在启动之前重新附加到进程名称。它会弹出一个模式对话框,说它正在等待进程名称启动。
现在启动进程,Visual Studio 调试器将立即附加,捕获异常并命中断点。
【讨论】:
一千次是的! 我遇到了死锁。它在我的目标启动时请求管理员身份验证,并且在输入 pwd 并重新启动 vs 后,重新附加就消失了。只有与没有管理员身份验证的对比包含重新附加。 对我不起作用。在崩溃已经发生之后,它仍然为时已晚。它似乎每秒检查一次现有进程,这对这个应用程序来说完全没有意义。【参考方案4】:我在寻找类似的东西时找到了这个答案。就我而言,我不能简单地将可执行文件用作我的项目的启动程序,因为它需要在我无法轻易复制的非常特定的环境中启动(即:从 cygwin 启动)。
我查看了作为 suggested by mrstrange 的重新附加扩展程序以及非常相似的 Attach To Anything 扩展程序...但我的可执行文件似乎关闭得太快,无法通知和附加扩展程序。
最终帮助我的是:https://***.com/a/4042545/1560865,它引用了 MSDN 文章 How to: Launch the Debugger Automatically,该文章又列出了以下步骤:
-
启动注册表编辑器 (regedit)。
在注册表编辑器中,打开 HKEY_LOCAL_MACHINE 文件夹。
导航到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\image 文件执行选项。
在 Image File Execution Options 文件夹中,找到您要调试的应用程序的名称,例如 myapp.exe。如果找不到要调试的应用程序:
一种。右键单击Image File Execution Options文件夹,然后在快捷菜单上单击New Key。
湾。右键单击新键,然后在快捷菜单上单击重命名。
C。将键名编辑为您的应用程序的名称; myapp.exe,在本例中。
右键单击myapp.exe 文件夹,然后在快捷菜单上单击新建字符串值。
右键单击新字符串值,然后在快捷菜单上单击重命名。
将名称更改为
debugger
。
右键单击新字符串值,然后在快捷菜单上单击修改。 编辑字符串对话框出现。
在数值数据框中,输入vsjitdebugger.exe
。
点击确定。
从注册表菜单中,点击退出。
包含 vsjitdebugger.exe 的目录必须在您的系统路径中。要将其添加到系统路径,请按照下列步骤操作:
一种。在经典视图中打开控制面板,然后双击系统。
湾。点击高级系统设置。
C。在系统属性中,点击高级标签。
d。在高级标签上,点击环境变量。
e.在环境变量对话框的系统变量下,选择Path,然后点击Edit按钮。
F。在 Edit System Variable 对话框中,将目录添加到 Variable value 框中。使用分号将其与列表中的其他条目分开。
G。单击确定关闭编辑系统变量对话框。
H。单击确定关闭环境变量对话框。
一世。单击确定关闭系统属性对话框。
现在,使用任何方法启动您的应用程序。 Visual Studio 将启动并加载应用程序。
希望这对以后的其他人有所帮助!
【讨论】:
以下是使用较新版本的 VS(截至 2019 年)的相同过程的说明:docs.microsoft.com/en-us/visualstudio/debugger/… 谢谢你们俩。我这样做了,但我收到“Visual Studio 即时调试器未通知应用程序正确启动”错误。为此,我开始进行更多调查,进一步阅读:***.com/questions/6677161/… 更多阅读即时调试器docs.microsoft.com/en-us/visualstudio/debugger/…【参考方案5】:您可以通过以下方式从您的代码中启动调试器
public static void Main(string[] args)
System.Diagnostics.Debugger.Launch();
但在发送您的应用程序之前,请不要删除此行。也许您想使用编译器标志来确定:
public static void Main(string[] args)
#if debug
System.Diagnostics.Debugger.Launch();
#endif
【讨论】:
对于所有等待某个外部进程启动应用程序的情况,这应该是公认的答案。【参考方案6】:您可以显示一个 MessageBox,这会阻止应用程序,然后您将调试器附加或重新附加到进程并单击“确定”继续:
MessageBox.Show("Attach process to debugger and click ok!");
您可以将其添加到 Form 构造函数中(如果您使用 winforms),因此这将在其他任何操作之前执行,除了组件的初始化:
public MainForm()
InitializeComponent();
MessageBox.Show("Attach process to debugger and click ok!");
完成调试后,注释掉该行。
【讨论】:
【参考方案7】:如果没有进程,则 Visual Studio 无法附加到它。
但是,您可以将项目的启动程序设置为项目输出之外的其他内容。
【讨论】:
我已经调查过我想做的事情是否正确,事实上确实如此。我的情况不是通常的 Visual Studio 调试案例。我有一个在 Visual Studio 中开发的 Excel 2010 模板项目,模板表有启动事件。我从 Visual Studio 运行此模板,在我的 Excel 工作表中添加一些数据并将文件保存在磁盘上。然后我可以打开这个也依赖于模板程序集的文件的唯一方法是从资源管理器中打开它,因此在这种情况下我无法调试启动事件,当然我在启动时会进行一些数据处理,比如数据绑定。跨度> 可能需要勾选"Enable native code debugging"(项目属性→Debug→Enable Debuggers) .【参考方案8】:一个可能适合许多人的小解决方案。
在exe将运行的第一行代码中,添加此命令
System.Threading.Thread.Sleep(20000)
这将使 exe 在开始处理任何内容之前休眠 20 秒。然后你有20秒的时间附加到进程中,可以通过ctrl+alt+p快速完成,然后找到进程,然后输入附加。
答案不多,但对我很有帮助:--)
【讨论】:
我必须调试一个用“C”编写的 CGI,我有源代码。我是一个简单易用的解决方案,有时间附加到后台进程。以上是关于如何将 Visual Studio 附加到尚未启动的进程?的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio - 以编程方式将调试器附加到远程进程