调试调用C# dll的VB6项目

8
我在这个问题上已经卡了几个小时了。希望有人遇到过类似的问题。
我们开发了一个 .Net(C#) 的原型dll,使用VS2010,希望能够在C#应用程序和VB6应用程序中调用此dll。
我的问题是:
是否可能调试调用 .Net dll 的 VB6 应用程序?我收到一个错误消息“自动化错误,系统找不到指定的文件”。
错误消息表明,我的VB6应用程序缺少一些东西才能找到 .Net dll。
我知道如果VB6应用程序已经编译并创建了.exe文件,则在使用.exe时,VB6将成功调用 .Net dll 功能。
但是很重要的是,我们可以通过VB6应用程序进行调试。不幸的是,调试不允许您跨越实例化 .Net DLL 的类对象的代码行。我好像做不到这点。
注意:我在论坛和MSDN文档中寻找解决方案,大多数都是解决在.NET中调用VB6 dll的问题;而我们需要做的恰恰相反。

注意:我已经注册了编译好的.NET(C#)程序集,并在VB6项目中引用了它。

然而,我找到了这两个页面,似乎是我们需要的解决方案,但这是一个用于调用使用VS2005生成的.NET(c#) dll的解决方案。当使用VS2010生成.NET(C#) dll时,这似乎不起作用。

site1 site2

如果有人能提供任何建议或指引我去哪里获取解决方案,那就太好了。

谢谢

解决方案 感谢@HansPassant,我找到了解决方案。 要调试包含C# .NET程序集的VB6项目,您需要通过“regasm”和“gacutil”注册.NET dll,然后确保在开始调试之前关闭并重新打开VB6应用程序。


2
如果我理解你的问题正确,你想从VB 6端进行调试(即从VB 6的IDE中)?这是不可能的 - VB 6调试器只能用于VB 6代码。它根本无法处理本地代码,当然也无法处理MSIL(.NET)代码,因为当VB 6发布时,这个概念甚至还没有被发明出来。 - Cody Gray
我猜这取决于你用来编译它的 .Net 框架。你找到的示例是相反的,因为 Visual Studio 版本试图保持向后兼容性。 - luchosrock
将您的.NET对象重新声明为"As Object"(暂时),应该会更好地工作。 - Arvo
仅供参考,您可以考虑使用单元测试和模拟.NET依赖项来满足此要求。我编写了自己的测试框架,所以无法提供太多帮助来寻找一个好的VB6单元测试框架,但应该不难找到合适的工具。 - Mike Burton
相关:https://dev59.com/OFjUa4cB1Zd3GeqPQEw9 - StayOnTarget
显示剩余6条评论
3个回答

12

这不是问题,VB6使用自己的调试器,不会影响任何其他调试器,包括C#代码的托管调试器。

您可以从C#类库项目开始,确保将其选为起始项目。选择“项目+属性”,打开“调试”选项卡。选择“启动外部程序”选项并输入VB6 IDE的路径。通常为c:\program files\microsoft visual studio\vb98\vb6.exe。在您想要调试的方法上设置断点。

按F5键,VB6 IDE 将开始运行。加载或创建您的vb6项目。请注意,您可以在上一步中添加 .vbp 项目的路径,这样它就会自动加载您的项目。

像往常一样开始调试您的vb6项目。只要开始使用您的[ComVisible] C#类,您的C#程序集就会被加载。当vb6代码调用该方法时,断点将触发。根据需要切换回和切换出。请注意,您无法从vb6逐步执行C#代码,您必须设置断点以使调试器停止。


嗨,汉斯,我刚试了你的解决方案。它出现了“自动化错误,系统找不到指定的文件”的错误。注意:.net dll包含一个[COMVisible(true)]类和方法。在vb6项目的同一目录中有C#程序集和.tlb的副本。最后,.Net程序集是使用VS2010编译的。在VB6中加载C#程序集是否有特定的方法? - Knoxxios
那是完全不同的问题,请确保提出来。简而言之,CLR 没有任何理由查找 vb6 项目目录,它对此一无所知。它会在 regasm.exe /codebase 目录和 GAC 中查找 [ComVisible] 程序集,以及在 vb98 目录和 GAC 中查找相关程序集。使用 Fuslogvw.exe 工具来查看。 - Hans Passant
很好,我认为这是可能的,但我没有尝试过,所以我不知道它们如何交互,因此才会说“不容易” :) - Deanna
@HansPassant 嗯,既然提到了GAC,我可能会再试一次……我没有使用gacutil注册.Net DLL,因为我在某个地方读到过,你只需要使用regasm注册.Net dll。我是VB6的新手(大部分时间都用C#编码),请原谅我的无知,我还在研究如何使用Fuslogvw.exe,谢谢。 - Knoxxios
@HansPassant ,我还更新了我的问题以澄清我的问题。谢谢。 - Knoxxios
@HansPassant 先生,您真是个天才。 "它在 regasm.exe /codebase 目录和 GAC 中查找 [ComVisible] 程序集以及 vb98 目录和 GAC 中的相关程序集"。我已经在 GAC 中注册了 Dll,现在似乎可以通过 VB6 代码和 .NET 代码进行调试 :D ...不过,我需要确认它是否真正起作用,需要测试它们之间传递的值是否正确,然后我会更新这个帖子。谢谢,不确定能否将您的评论标记为答案 :S - Knoxxios

3
啊,使用.NET从VB6中以可调试的方式工作真是太神奇了。
  • 在VB6项目编译选项(通过Make Project对话框窗口上的Options按钮打开)中,选择编译为本机代码不进行优化创建符号调试信息 选项。然后编译你的VB6项目。这些选项允许正确的VB6二进制到源码的映射。
  • 转到你的解决方案的Configuration Properties... Debugging属性页面并将Start Action 更改为启动你的VB6可执行文件。
  • 在VS Solution Explorer中,转到File... Add Existing Item并导航到包含你想要调试的VB6源代码的文件夹。双击你想要调试的VB6源代码文件,一个源代码窗口应该会在VS中打开,允许你在VB6源代码中设置断点。
  • 确保你的.NET库有一个公共默认构造函数。这是必要的。
  • 现在也设置任何你需要的C#断点。不要步入.NET代码-这不起作用。
  • 当你使用VS开始调试时,你的VB6和C#断点应该能够正常触发。

我按照你的步骤操作,但是没有打开源代码窗口,希望你不是指我可以在VS2010中打开VB6代码。 - Knoxxios
@Knoxxios,是的,你可以在VS2010中打开和调试VB6源代码。我刚刚做到了。当你双击VB6源代码文件时发生了什么? - HTTP 410
源文件打开得很好(正如预期的那样,它显示了C#项目中的错误,但这不会影响C#项目(再次符合预期))。问题是我无法通过VB6源代码进行调试 :( - Knoxxios
@Knoxxios,你是否按照我第一个要点的建议编译了你的VB6可执行文件? - HTTP 410
是的,我做了;我使用你建议的设置编译了它。 - Knoxxios

1
一种方法是单独调试每个部分:
  • 在编译C# DLL并将其作为参考添加到VB6项目后,可以在IDE中调试VB6代码。

  • 在Visual Studio中,通过编译VB6项目并将其用作可执行文件来使用VB6主机调试DLL。

在某些情况下,这比同时设置环境来调试两者更简单/更快。

此方法要求至少先使每个框架正常工作。


当你说:“在编译和引用C# DLL之后,可以在IDE中单独调试VB6代码。”你的意思是创建可执行文件吗? - Knoxxios
@Knoxxios 不是编译DLL。要调试或测试,您需要另一个已编译的文件。因此首先需要一个基本框架。我稍微更新了我的答案以澄清。 - Deanna
哦,如果是这样的话,我已经尝试过了。我已经编译了C#程序集并在VB6项目中引用它。我可以使用您的建议调试C# dll,但无法调试VB6项目。 - Knoxxios

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