4

I am trying to do a Jenkins-based automated build/deployment of a web application (.NET 4.0). The web application project has several project references, which in turn have binary references third party DLLs.

The problem:

  1. The second-level references (references of project references) are not pulled into the bin folder in the obj\<CONFIGURATION>\Package\PackageTmp\bin folder, used for building deployment packages.
  2. When I build in the visual studio, the second level references are pulled into the regular build output directory.
  3. When building with MSBuild, second level dependencies are not pulled into the regular output directory, nor into the PackageTmp\bin directory.

This is confirmed by MS as a Won't-Fix issue here.

Related questions here, here and here either do not match my problem, or offer solutions that don't work. I've reviewed all answers, not just the accepted ones.

My build command looks like this (using MSBuild 4.0):

MSBuild MySolution.sln /p:Configuration=Integration /p:platform="Any CPU" /t:Clean,Build /p:DeployOnBuild=true /p:DeployTarget=Package /p:AutoParameterizationWebConfigConnectionStrings=false

I've tried to manually edit Reference elements in project files, adding <Private>True</Private>, with no success.

I am trying to work around this known issue, so that my second-level dependencies are automatically and correctly pulled into the web publishing temp directory.

My current attempt combines the general approach here (customizing the web publishing pipeline by adding a MyProject.wpp.targets file next to the web project file), combined with some MSBuild code for finding DLLs here. So far this has either produced no results or broken the project file. I am new to custom MSBuild code and find it pretty arcane.

My Question: I am looking for a more complete example that works in my specific case. I think the goal is to intervene in the web publishing pipeline that gathers files for copying to the package temp directory, and adding the second-level dependencies to it.

My custom MyWebProj.wpp.targets looks like this:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
      <BRPathFiles Include="$(SolutionDir)..\Common\**\*.dll;$(SolutionDir)**\*.dll" />
      <ConfigPathFiles Include="$(SolutionDir)..\Common\**\*.config;$(SolutionDir)**\*.config" />
    </ItemGroup>

    <Target Name="CopySecondLevelDependencies" BeforeTargets="CopyAllFilesToSingleFolderForPackage">
      <RemoveDuplicates Inputs="@(BRPathFiles->'%(RootDir)%(Directory)')">    
        <Output TaskParameter="Filtered" ItemName="BRPaths" />
      </RemoveDuplicates>
      <RemoveDuplicates Inputs="@(ConfigPathFiles->'%(RootDir)%(Directory)')">    
        <Output TaskParameter="Filtered" ItemName="ConfigPaths" />
      </RemoveDuplicates>    

      <CreateItem Include="%(BRPaths.Identity);%(ConfigPaths.Identity);">
        <Output ItemName="FileList" TaskParameter="Include"/>
      </CreateItem>

      <CreateItem Value="@(BRSearchPath);$(ConfigSearchPath)">
        <Output TaskParameter="Value" PropertyName="SecondLevelFiles" />
      </CreateItem>
    </Target>       
    <ItemGroup>
      <FilesForPackagingFromProject
        Include="%(SecondLevelFiles->'$(OutDir)%(FileName)%(Extension)')">
        <DestinationRelativePath>$(_PackageTempDir)\bin\%(FileName)%(Extension)       </DestinationRelativePath>
        <FromTarget>CopySecondLevelDependencies</FromTarget>
        <Category>Run</Category>
      </FilesForPackagingFromProject>
    </ItemGroup>
</Project>
Community
  • 1
  • 1
Udi Bar-On
  • 791
  • 1
  • 7
  • 20

1 Answers1

0

Assuming you have collected all libraries needed at runtime in a folder outside your solution/project, have you tried just using post-build events to copy all these libraries to your main project target directory (bin) and then include that directory in your deployment package using Sayeds method: http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx (also available in this post: How do you include additional files using VS2010 web deployment packages?)?

I have (among others) the following line in my main project's post-build events:

xcopy "$(ProjectDir)..\..\Libraries\*.dll" "$(TargetDir)" /Y /S

In addition to this, I have added the following lines to my .csproj file:

<PropertyGroup>
  <CopyAllFilesToSingleFolderForPackageDependsOn>
    PostBuildLibraries;
    $(CopyAllFilesToSingleFolderForPackageDependsOn);
  </CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
    <Target Name="PostBuildLibraries">
  <ItemGroup>
    <_PostBuildLibraries Include="$(TargetDir)**\*" />
    <FilesForPackagingFromProject Include="%(_PostBuildLibraries.Identity)">
      <DestinationRelativePath>$(OutDir)%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
</Target>

Be sure to add these lines after the import of the "Microsoft.WebApplication.targets". Check out the links above for more details.

This makes all the desired libraries available after each build (copied to the project's target directory) and each time I create a deployment package (copied to the obj\<CONFIGURATION>\Package\PackageTmp\bin).

Also, since I'm building my main project, not my solution, I'm using the $(ProjectDir) macro instead of the $(SolutionDir).

Community
  • 1
  • 1
Mattias Larsson
  • 175
  • 2
  • 6