调试来自.net core 2.0中动态加载程序集的代码

时间:2017-09-06 11:56:42

标签: c# .net .net-core

我有一个.net core 2.0控制台应用程序执行以下操作(简化):

var a = Assembly.Load(Assembly.GetEntryAssembly()
                              .GetReferencedAssemblies()
                              .First(i => i.Name == "MyAssembly"));

var t = a.GetType("MyType");
var i = (MyBaseType)Activator.CreateInstance(t);

i.Execute();

当我通过代码进行调试时,它按预期进入MyType.Execute()

但是,如果我使用以下代码加载程序集:

var path = new FileInfo(Assembly.GetExecutingAssembly().Location);
var a = Assembly.LoadFile(Path.Combine(path.DirectoryName, "MyAssembly.dll"));

代码仍然有效但我在调试时无法进入MyType.Execute()

任何想法为什么/什么是错的?

5 个答案:

答案 0 :(得分:10)

这可能是由于应用程序无法找到与MyAssembly程序集关联的PDB文件引起的,如其中一条评论中所述。但是,似乎PDB文件在与程序集相同的文件夹中不需要进行调试工作。

为了检查符号是否已加载,请在调用Assembly.LoadFile()后打开一个断点并打开 模块 窗口(可以找到它)在Visual Studio中的 Debug \ Windows 菜单中。在此窗口中,找到MyAssembly程序集并验证 符号状态 列中的值。如果缺少PDB是原因,则值为" 无法找到或打开PDB文件。"。您还可以使用该窗口查看调试器尝试查找符号文件的位置。

调试器在多个位置查找PDB文件,如下所述: Specify Symbol (.pdb) and Source Files in the Visual Studio Debugger

根据文章,PDB文件的默认位置是:

  1. 在程序集本身内指定的位置(在编译程序集时由链接器放置)
  2. 动态加载的程序集所在的文件夹
  3. 本地符号缓存文件夹
  4. 互联网,网络或本地符号服务器
  5. 我想在你的情况下,应该考虑提到的第一个或第二个位置。

    另一个需要注意的重要事项是PDB必须与程序集完全匹配,因此在重新编译程序集后,还应更新PDB文件以匹配新版本。

    如果PDB文件与程序集匹配并位于上述某个位置,您应该能够调试代码。

    可能还有其他原因,这与使用.NET Core的事实没有直接关系,但我认为正确的PDB加载可能值得验证。

答案 1 :(得分:4)

您是否选中了just my code选项?

enter image description here

  

启用我的代码

     

("我的代码"),忽略系统代码和其他代码   优化或没有调试符号。调试器显示并进入用户代码

也许应该取消选中?

答案 2 :(得分:3)

我同意Lukasz和Alexan的答案。如果您已经检查过这些并且它不起作用,那么您的代码示例之所以不同,可能是因为它们没有加载相同的程序集。

执行的装配和输入装配并不总是相同的装配,因此路径可以不同。也可能是加载了另一个版本的程序集,例如从GAC加载。使用Visual Studio中的模块窗口,您可以看到加载了哪个DLL。如果存在正确的PDB并且Just Me Code已关闭,您应该能够进入它。

答案 3 :(得分:1)

有一个'Assembly.Load'覆盖,它将PDB数据作为参数。您需要显式加载调试符号。

检查此SO帖子:Debug dynamically loaded assembly

另请参阅MSDN:https://msdn.microsoft.com/en-us/library/twt16z2x(v=vs.110).aspx

希望这有帮助

答案 4 :(得分:1)

如果使用Assembly.LoadFile方式,您的代码将无法编译。

我已经在Visual Studio 2017社区中创建了一个示例项目,并且我能够使用Assembly.LoadFileAssembly.Load两种方式从动态程序集中进入函数。我没有和你一起使用代码,因为它没有编译,但我会提供一个解决方案,我认为你将解决你的问题。

以下是解决方案: 完整的解决方案就在这里 https://github.com/beyazc/.netcore-dynamic-assembly-debug

基本上我能用以下代码进行调试。你应该在调用方法

上按f11
var assemlies = Assembly.GetEntryAssembly().GetReferencedAssemblies();
        var assemblyName = "";
        foreach (var item in assemlies)
        {
            if (item.Name == "RefProj")
                assemblyName = item.Name;

        }
        var path = new FileInfo(Assembly.GetExecutingAssembly().Location);
        var a = Assembly.LoadFile(Path.Combine($@"{path}\..\..\..\..\..\RefProj\bin\Debug\netstandard2.0", "RefProj.dll"));
        var t = a.GetType("RefProj.Class1");

        var i = Activator.CreateInstance(t);
        MethodInfo mi = t.GetMethod("get1");
        mi.Invoke(i, null);