C# 为什么我会得到;System.IO.FileNotFoundException:无法加载文件或程序集;当设置“引用”时;copylocal=false";?

C# 为什么我会得到;System.IO.FileNotFoundException:无法加载文件或程序集;当设置“引用”时;copylocal=false";?,c#,visual-studio,unit-testing,filenotfoundexception,copy-local,C#,Visual Studio,Unit Testing,Filenotfoundexception,Copy Local,情况是这样的:我试图使用一个我称之为“TestProject”的测试项目来运行单元测试。它是在另一个项目中测试一个类,我称之为“Class1”和“Project1” Project1在运行时对各种dll进行动态延迟加载,我称之为“动态dll”。Project1通过查找与其自身构建输出路径相关的目录来查找这些dll 问题的第一部分出现在TestProject引用Project1时。显然,它会将新构建的Project1.dll复制到自己的构建目录中,然后当Project1.dll在相对于其位置的路径

情况是这样的:我试图使用一个我称之为“TestProject”的测试项目来运行单元测试。它是在另一个项目中测试一个类,我称之为“Class1”和“Project1”

Project1在运行时对各种dll进行动态延迟加载,我称之为“动态dll”。Project1通过查找与其自身构建输出路径相关的目录来查找这些dll

问题的第一部分出现在TestProject引用Project1时。显然,它会将新构建的Project1.dll复制到自己的构建目录中,然后当Project1.dll在相对于其位置的路径中查找动态dll时,它找不到动态dll,因为它是从TestProject的位置运行的,而不是从自己的位置运行的

为了解决这个问题,我转到TestProject的引用,右键单击Project1引用,并打开它的属性。然后我将“复制本地”设置为“False”。我还确保引用的“Path”属性与Project1的构建路径相同

现在我有了一个新问题,我甚至不知道它是什么。每当我运行单元测试时,它都会失败,并报告“System.IO.FileNotFoundException:无法加载文件或程序集[将Project1命名为不可查找程序集的信息]”

此外,当我试着调试单元测试时,而不是仅仅运行它,它从不抛出异常、抱怨或其他任何东西,从而阻止我进一步了解有关问题的信息。我在测试报告中也找不到任何进一步的有用信息

以下是完整的测试报告,其中包含名称和出于保密目的而交换的内容:

Test Name:  Class1_Tests
Test FullName:  TestProject.TestClass.Class1_Tests
Test Source:    c:\Code\Solution1\Tests\TestProject\TestClass.cs : line 175
Test Outcome:   Failed
Test Duration:  0:00:00.0348455

Result Message: 
Test method TestProject.TestClass.Class1_Tests threw exception: 
System.IO.FileNotFoundException: Could not load file or assembly 'Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: DisplayName = Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Code/Solution1/Tests/TestProject/bin/Debug
LOG: Initial PrivatePath = NULL
Calling assembly : TestProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Code\Solution1\Tests\TestProject\bin\Debug\TestProject.dll.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.DLL.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1.EXE.
LOG: Attempting download of new URL file:///C:/Code/Solution1/Tests/TestProject/bin/Debug/Project1/Project1.EXE.
Result StackTrace:  at TestProject.TestClass.Class1_Tests()
从日志中可以看出,TestProject似乎仍在尝试从其自身的#$%^ing生成路径加载Project1的dll,尽管我明确告诉它不要复制本地。(grrrr…)


我做错了什么?

!!!请注意:我发布的原始问题是关于我解决更深层问题的方法的问题。这个答案是对更深层次问题的解决方案,而不是问题所涉及的问题

进一步解释:最初的问题是,当引用设置为“CopyLocal=false”时,如何让运行时环境正确加载引用的依赖项

之所以提出这个问题,是因为我一直在设置copylocal=false,以保持依赖项dll在其原始构建路径中运行,即使它是作为不同单元测试项目的一部分加载和运行的,以便它能够在运行时找到相对于其构建路径位于文件夹路径中的项

这个答案是对第一个问题的回答,从一开始就不需要设置copylocal=false。因此,我不会选择我在这里的答案作为最有帮助的答案。如果有人对这个直接的问题有答案,他们仍然应该把它贴出来,以帮助那些可能因为与我不同的原因而与这个问题作斗争的人

这就是说,以下是我对设置copylocal=false所需的I原因的解决方案:

  • 将动态DLL添加到项目1,但不作为引用。只需在解决方案资源管理器中右键单击Project1并选择“添加现有项”,然后浏览到每个dll位置并将其添加为链接。(重要的是添加为链接,这样每当由其dynamicdellproject重建时,它都会被刷新)
  • 右键单击Project1中新添加的项目并选择“属性”。将“构建操作”设置为“无”,并将“复制到输出目录”设置为“更新时复制”“始终复制”
  • 对Project1将/可能在运行时加载的每个动态dll重复步骤1和2
  • 当然,在TestProject中,我将Project1引用设置回“Copy Local=True”
  • 这样做的效果是,虽然动态dll实际上没有被引用或编译到Project1中(当Project1运行时,应该避免它们被急于加载),但是任何引用Project1并将其dll复制到其输出路径的项目也会复制到作为该项目输出一部分添加的项上(在本例中为动态DLL)


    我希望这能帮助任何有这个问题的人,原因和我一样。

    听起来好像有一个不应该存在的对源代码树的依赖。不管正在构建的项目是什么,我认为DLL解析应该从“当前”开始生成输出目录,而不是从某些硬编码的生成输出目录。如果TestProject1引用Project1,则生成Project1的结果应该在TestProject1的输出中。这完全正常。非常不清楚为什么您希望它以另一种方式工作,或者为什么Copy Local=True不合适。每个.NET程序员都有阅读并理解他们是否想要修改默认设置。