MSBuild可以正确构建具有项目引用的项目,但无法从解决方案中构建。

10

当我构建一个包含两个项目B.csproj和C.csproj的A.sln,并且这些项目具有内部项目引用时,它会在MSBuild中抛出引用错误。但是,当我在MSBuild中单独构建B.csproj和C.csproj时,它不会抛出错误。而且,在VS IDE中构建A.sln也不会抛出错误。我正在使用.NET 2.0框架。请查看下面用于构建sln和projs的脚本。

MSBuild "<path>/A.sln" /p:Configuration=Release /p:StartupObject="" /p:WarningLevel=4 /p:Optimize=true /t:rebuild /l:Filelogger,Microsoft.Build.Engine;logfile=F:\A.sln.log /verbosity:normal

MSBuild "<path>/B.csproj" /p:Configuration=Release /p:StartupObject="" /p:WarningLevel=4 /p:Optimize=true /t:rebuild /l:Filelogger,Microsoft.Build.Engine;logfile=F:\B.csproj.log /verbosity:normal 

MSBuild "<path>/C.csproj" /p:Configuration=Release /p:StartupObject="" /p:WarningLevel=4 /p:Optimize=true /t:rebuild /l:Filelogger,Microsoft.Build.Engine;logfile=F:\C.csproj.log /verbosity:normal 

编辑:

所有抛出的错误都是由于缺少引用的代码引起的(全部都是项目引用)。我只得到了三种类型的错误,如下所示。

error CS0012: 类型“X”在未被引用的程序集中定义。您必须添加对程序集“Y、版本=2.0.0.0、Culture=neutral、PublicKeyToken=aad4cbe5d7c27078”的引用。

error CS0234: 类型或命名空间名称“X”在命名空间“Y”中不存在(是否缺少程序集引用?)

error CS0246: 无法找到类型或命名空间名称“X”(是否缺少 using 指令或程序集引用?)

在构建路径之前,我从IDE和MSBuild清除了所有先前构建的dll。但是IDE很好用,在“引用”部分中不显示任何缺失的引用指示器。

没有在IDE中手动添加任何引用路径。

另一个更新:

我刚刚注意到,当我从解决方案打开这两个项目时,引用在IDE中正确地指向。但是当我单独在IDE中打开这些项目时,我提到的缺失引用就会出现在MSBuild中。非常奇怪。

所以总结一下,

在MSBuild中构建.proj - 良好

在IDE中构建.proj - 错误

在MSBuild中构建.sln - 错误

在IDE中构建.sln - 良好

对我来说看起来非常奇怪。非常感谢您的帮助。


9
当你在提问并指出错误时,将错误信息剪切并粘贴过来是非常有帮助的。这适用于异常、编译器错误、构建错误等情况。 - Jon Skeet
顺便提一下,如果两个项目单独构建没有问题,那么我想知道这两个项目是否需要项目引用。另一方面,这可能是由于最近的功能使得MSBUILD能够“智能”处理项目引用而导致的。由于我从未理解过该功能,因此我不能排除这种可能性;但我建议您确认所有项目引用是否都是必需的,并且重新构建B是否会导致C的重建。 - John Saunders
@blntechie:感谢您的更新。我建议您使用“解决方案资源管理器”;按顺序选择每个引用,并查看属性窗口中的详细信息。是否发现任何奇怪的情况,例如一个在 obj 中,而其他引用在 bin 中?此外,如果没有引用路径,则可以查看您的 .csproj.user 文件,以确保确实没有引用路径? - John Saunders
@John Saunders:感谢您的帮助。我刚刚注意到,当我从解决方案中打开这两个项目时,参考在 IDE 中正确地指向。但当我单独在IDE中打开这些项目时,我提到的缺少的引用出现在 MSBuild 中。非常奇怪。非常感谢您的帮助。我也会更新问题。 - lakshminb7
你是怎么解决这个问题的?我也遇到了同样的问题... - Ignacio Soler Garcia
在VS2015中看到相同的东西 - 非常奇怪。解决方案在Visual Studio中构建良好,但在MSBUILD(在构建服务器上和本地开发机器上)失败。我注意到,实际上构建了失败的项目(如CSC.EXE被调用)总共三次 - 前两个编译明显包括所有项目引用,但第三个编译缺少项目引用。我已经花费了几个小时查看/v:diagnostic跟踪,并且无法解释这里发生了什么。 - lesscode
5个回答

8

MSBuild和VS都使用项目引用和项目依赖项来选择解决方案的构建顺序。除此之外,这是未定义的 - 通常在两者之间有所不同。请检查这两者是否正确。项目依赖关系设置在您解决方案的属性中。

如果这样做没有效果,请仔细检查项目引用中的GUID是否与解决方案中的GUID匹配。有时重新创建解决方案可以修复它们。


4

对于我来说,当我遇到这个(或类似的)问题时,手动检查(和修复)guids是否匹配可以解决我的问题。在.sln和.csproj文件之间跟踪guids很麻烦,但它有效。

我通常会删除项目引用并重新添加它,这样就可以解决问题(一旦我找到了不匹配的guids)。也许我应该先尝试这个。这更容易。


1
同样的方法对我也起作用了。我发现找出哪些GUID不匹配的最好方法是将Visual Studio排除在外,尝试使用纯MSBuild进行构建,这样错误就会浮出水面。请参阅此文章以了解如何执行此操作:http://www.codeproject.com/Tips/177770/Creating-MSBuild-projects-from-sln-files.aspx - rohancragg

3
一些需要考虑的事情:在IDE中构建解决方案并不等同于在.sln文件上运行MSBUILD。你可以尝试使用devenv.exe /rebuild A.sln。IDE会玩一些游戏来允许.sln文件构建,包括创建一个“等效”的MSBUILD风格项目。
此外,IDE并不直接生成MSBUILD命令。两者之间存在互动以提高性能。例如,项目中的CSC任务可能在IDE内部执行,而不是作为单独的命令行构建,就像MSBUILD会生成它们一样。
还应该考虑从http://technet.microsoft.com/sysinternals/获取进程监视器,以查看哪些文件正在被访问。

1

从GAC(C:\ WINDOWS \ assembly文件夹 - 选择您的程序集,右键单击并卸载)中删除程序集。

因为解决方案使用guid保留引用,如果该guid在GAC中,则会继续使用GAC版本进行编译。


1

正如Jon Skeet所提到的,错误信息对于了解问题是有帮助的。但是如果没有任何细节,如果它在IDE中构建但在MSBuild中无法构建,那么听起来你可能在项目中引用了DLL文件,而这些文件在构建解决方案的路径中不可用。也许你手动将它们复制到IDE可以找到它们的某个地方,或者你在IDE中设置了引用路径以查找某个文件夹。

在获取其他详细信息时,请检查一下这些内容。

编辑:现在有了一些细节,可能是构建顺序的问题。B项目中是否有对C项目的引用?如果是,你可能只需要更改构建顺序,先构建C项目再构建B项目。


在我的情况下,Proj C 引用了 Proj B。而且 Proj B 在 Proj C 之前构建。 - lakshminb7

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