为了账号安全,请及时绑定邮箱和手机立即绑定

如果在解决方案中使用项目依赖项,MSBuild不复制引用(DLL文件)

如果在解决方案中使用项目依赖项,MSBuild不复制引用(DLL文件)

如果在解决方案中使用项目依赖项,MSBuild不复制引用(DLL文件)我的VisualStudio解决方案中有四个项目(每个项目都针对.NET 3.5)-对于我的问题,只有这两个项目很重要:MyBaseProject <- this class library references a third-party DLL file (elmah.dll)MyWebProject 1 <- this web application project has a reference to MyBaseProject我添加了elmah.dll引用MyBaseProject在VisualStudio 2008中,单击“AddReference.”→“Browse”选项卡→,选择“elmah.dll”。Elmah引用的属性如下:别名-全局复制本地-真文化-描述-用于ASP.NET的错误日志记录模块和处理程序(ELMAH)文件类型-程序集路径-D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll解决-真运行时版本-v2.0.50727指定版本-假强名称-假版本-1.0.11211.0在……里面MyWebProject 1我通过以下方式添加了对ProjectMyBaseProject的引用:“AddReference.”→“Projects”选项卡→选择“MyBaseProject”。除下列成员外,此引用的属性相同:描述-路径-D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll版本-1.0.0.0如果我在VisualStudio将elmah.dll文件复制到我的MyWebProject 1垃圾箱目录,以及MyBaseProject.dll!但是如果我清理和跑MSBuild对于解决方案(通过D:\webs\CMS>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe/t:重构/p:配置=Debug MyProject.sln)elmah.dll失踪在MyWebProject 1的bin目录中-尽管构建本身不包含警告或错误!我已经确保MyBaseProject的.csproj包含私元素,其值为“true”(应该是“复制本地“在VisualStudio中):<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>(默认情况下,私有标记没有出现在.csproj的XML中,尽管VisualStudio说“复制本地”为true。我将“复制本地”切换为假保存-并将其重新设置为true-保存!)MSBuild有什么问题?如何将(elmah.dll)引用复制到MyWebProject 1的bin中?我不想在每个项目的后置命令中添加一个后期复制操作!(想象一下,我会有许多项目依赖于MyBaseProject!)
查看完整描述

3 回答

?
DIEA

TA贡献1820条经验 获得超2个赞

我不知道在VisualStudio和MsBuild之间构建时为什么会有所不同,但下面是我在MsBuild和VisualStudio中遇到这个问题时所发现的。

解释

对于一个示例场景,假设我们有项目X、程序集A和程序集B。程序集A引用程序集B,所以项目X包括对A和B的引用。此外,项目X包括引用程序集A的代码(例如A.SomeFunction()。现在,创建一个引用项目X的新项目Y。

因此,依赖链如下所示:Y=>X=>A=>B

Visual Studio/MSBuild试图保持智能,只将引用带到它检测到项目X所需的项目Y中;它这样做是为了避免项目Y中的引用污染。问题是,由于项目X实际上没有包含任何显式使用程序集B的代码(例如B.SomeFunction(),VS/MSBuild不会检测到X需要B,因此不会将其复制到项目Y的bin目录中;它只复制X和A程序集。

您有两个解决此问题的选项,这两个选项都将导致程序集B被复制到项目Y的bin目录中:

  1. 在项目Y中添加对程序集B的引用。
  2. 将虚拟代码添加到项目X中使用程序集B的文件中。

就我个人而言,出于几个原因,我更喜欢备选方案2。

  1. 如果您以后添加了引用项目X的另一个项目,您将不必记住也包括对程序集B的引用(就像您在选项1中所做的那样)。
  2. 您可以有明确的注释,说明为什么虚拟代码需要在那里,而不是删除它。因此,如果有人无意中删除了代码(例如,使用一个寻找未使用代码的重构工具),您可以从源代码管理中很容易地看到该代码是必需的,并进行还原。如果使用选项1,而有人使用重构工具来清除未使用的引用,则没有任何注释;您只会看到.csproj文件中删除了引用。

下面是我通常在遇到这种情况时添加的“虚拟代码”的示例。

    // DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
    private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
    {
        // Assembly A is used by this file, and that assembly depends on assembly B,
        // but this project does not have any code that explicitly references assembly B. Therefore, when another project references
        // this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
        // assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
        // gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
        var dummyType = typeof(B.SomeClass);
        Console.WriteLine(dummyType.FullName);
    }


查看完整回答
反对 回复 2019-07-01
?
弑天下

TA贡献1818条经验 获得超8个赞

如果您没有在代码中直接使用程序集,则VisualStudio在尝试帮助时检测没有使用它,并且没有将它包含在输出中。我不知道您为什么会看到VisualStudio和MSBuild之间的不同行为。您可以尝试将构建输出设置为两种类型的诊断,并比较结果,查看其发散点。

对于elmah.dll引用,如果没有在代码中直接引用它,可以将其作为项目项添加到项目中,并将BuildAction设置为Content以及输出目录的副本到Always.


查看完整回答
反对 回复 2019-07-01
  • 3 回答
  • 0 关注
  • 1230 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信