MSBuild doesn't copy references (DLL files) if

2018-12-31 12:40发布

I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:

  1. MyBaseProject <- this class library references a third-party DLL file (elmah.dll)
  2. MyWebProject1 <- this web application project has a reference to MyBaseProject

I added the elmah.dll reference to MyBaseProject in Visual studio 2008 by clicking "Add reference..." → "Browse" tab → selecting the "elmah.dll".

The Properties of the Elmah Reference are as follows:

  • Aliases - global
  • Copy local - true
  • Culture -
  • Description - Error Logging Modules and Handlers (ELMAH) for ASP.NET
  • File Type - Assembly
  • Path - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
  • Resolved - True
  • Runtime version - v2.0.50727
  • Specified version - false
  • Strong Name - false
  • Version - 1.0.11211.0

In MyWebProject1 I added the reference to Project MyBaseProject by: "Add reference..." → "Projects" tab → selecting the "MyBaseProject". The Properties of this reference are the same except the following members:

  • Description -
  • Path - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
  • Version - 1.0.0.0

If I run the build in Visual Studio the elmah.dll file is copied to my MyWebProject1's bin directory, along with MyBaseProject.dll!

However if I clean and run MSBuild for the solution (via D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln) the elmah.dll is missing in MyWebProject1's bin directory - although the build itself contains no warning or errors!

I already made sure that the .csproj of MyBaseProject contains the private element with the value "true" (that should be an alias for "copy local" in Visual Studio):

<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
    **<Private>true</Private>**
</Reference>

(The private tag didn't appear in the .csproj's xml by default, although Visual Studio said "copy local" true. I switched "copy local" to false - saved - and set it back to true again - save!)

What is wrong with MSBuild? How do I get the (elmah.dll) reference copied to MyWebProject1's bin?

I do NOT want to add a postbuild copy action to every project's postbuild command! (Imagine I would have many projects depend on MyBaseProject!)

17条回答
像晚风撩人
2楼-- · 2018-12-31 13:03

I just had the exact same problem and it turned out to be caused by the fact that 2 projects in the same solution were referencing a different version of the 3rd party library.

Once I corrected all the references everything worked perfectly.

查看更多
后来的你喜欢了谁
3楼-- · 2018-12-31 13:04

If you are not using the assembly directly in code then Visual Studio whilst trying to be helpful detects that it is not used and doesn't include it in the output. I'm not sure why you are seeing different behaviour between Visual Studio and MSBuild. You could try setting the build output to diagnostic for both and compare the results see where it diverges.

As for your elmah.dll reference if you are not referencing it directly in code you could add it as an item to your project and set the Build Action to Content and the Copy to Output Directory to Always.

查看更多
牵手、夕阳
4楼-- · 2018-12-31 13:05

As Alex Burtsev mentioned in a comment anything that’s only used in a XAML resource dictionary, or in my case, anything that’s only used in XAML and not in code behind, isn't deemed to be 'in use' by MSBuild.

So simply new-ing up a dummy reference to a class/component in the assembly in some code behind was enough convince MSBuild that the assembly was actually in use.

查看更多
看淡一切
5楼-- · 2018-12-31 13:06

Including all referenced DLL files from your projectreferences in the Website project is not always a good idea, especially when you're using dependency injection: your web project just want to add a reference to the interface DLL file/project, not any concrete implementation DLL file.

Because if you add a reference directly to an implementation DLL file/project, you can't prevent your developer from calling a "new" on concrete classes of the implementation DLL file/project instead of via the interface. It's also you've stated a "hardcode" in your website to use the implementation.

查看更多
闭嘴吧你
6楼-- · 2018-12-31 13:10

I just ran into a very similar issue. When compiling using Visual Studio 2010, the DLL file was included in the bin folder. But when compiling using MSBuild the third-party DLL file was not included.

Very frustrating. The way I solved it was to include the NuGet reference to the package in my web project even though I'm not using it directly there.

查看更多
笑指拈花
7楼-- · 2018-12-31 13:12

The issue I was facing was I have a project that is dependent on a library project. In order to build I was following these steps:

msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package

That of course meant I was missing my library's dll files in bin and most importantly in the package zip file. I found this works perfectly:

msbuild.exe myproject.vbproj /T:Rebuild;Package

I have no idea why this work or why it didn't in the first place. But hope that helps.

查看更多
登录 后发表回答