我有一个.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()
。
任何想法为什么/什么是错的?
答案 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文件的默认位置是:
我想在你的情况下,应该考虑提到的第一个或第二个位置。
另一个需要注意的重要事项是PDB必须与程序集完全匹配,因此在重新编译程序集后,还应更新PDB文件以匹配新版本。
如果PDB文件与程序集匹配并位于上述某个位置,您应该能够调试代码。
可能还有其他原因,这与使用.NET Core的事实没有直接关系,但我认为正确的PDB加载可能值得验证。
答案 1 :(得分:4)
答案 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.LoadFile
和Assembly.Load
两种方式从动态程序集中进入函数。我没有和你一起使用代码,因为它没有编译,但我会提供一个解决方案,我认为你将解决你的问题。
以下是解决方案: 完整的解决方案就在这里 https://github.com/beyazc/.netcore-dynamic-assembly-debug
基本上我能用以下代码进行调试。你应该在调用方法
上按f11var 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);