Reputation: 27360
I have my own nuget package, that contains some native dll files.
When I build project, that references the nuget package, I want all native files from the nuget package to be copied into output directory.
How to create such nuget pacakge that copies the files into output dir?
I've tried to use Baseclass.Contrib.Nuget.Output, but I can't get it work on my Build Server (TFS 2013):
C:\Builds\1\MyProject\BuildName\src\MyProject\Packages\Baseclass.Contrib.Nuget.Output.2.1.0\build\net40\Baseclass.Contrib.Nuget.Output.targets (73): The source file for this compilation can be found at: "C:\Users\MHABLDSvc\AppData\Local\Temp\fd4f7f9d-59e3-4f6a-af8c-6a48deb7af3e.txt"
C:\Builds\1\MyProject\BuildName\src\MyProject\Packages\Baseclass.Contrib.Nuget.Output.2.1.0\build\net40\Baseclass.Contrib.Nuget.Output.targets (73): An error has occurred during compilation. error CS1705: Assembly 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' uses 'Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
C:\Builds\1\MyProject\BuildName\src\MyProject\Packages\Baseclass.Contrib.Nuget.Output.2.1.0\build\net40\Baseclass.Contrib.Nuget.Output.targets (73): The "PackageFilter" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with in the project file, or in the *.tasks files located in the "C:\Program Files (x86)\MSBuild\14.0\bin\amd64" directory.
C:\Builds\1\MyProject\BuildName\src\MyProject\Packages\Baseclass.Contrib.Nuget.Output.2.1.0\build\net40\Baseclass.Contrib.Nuget.Output.targets (73): An error has occurred during compilation. error CS1705: Assembly 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' uses 'Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
C:\Builds\1\MyProject\BuildName\src\MyProject\Packages\Baseclass.Contrib.Nuget.Output.2.1.0\build\net40\Baseclass.Contrib.Nuget.Output.targets (73): The "PackageFilter" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with in the project file, or in the *.tasks files located in the "C:\Program Files (x86)\MSBuild\14.0\bin\amd64" directory.
Upvotes: 0
Views: 911
Reputation: 14383
You could write some MSBuild logic to do this. I haven't tested this code but you could use something similar to the following (with tweaking):
<Target Name="AfterBuild">
<ItemGroup>
<NugetDlls Include="$(SolutionDir)\packages\mypackage\**\*.dll" />
</ItemGroup>
<Copy SourceFiles="@(NugetDlls)" DestinationFolder="$(OutputPath)" />
</Target>
You can even automate this change via Nuget using a start.ps1 PowerShell script in the Tools directory. In this case I would create a separate .targets file with the MSBuild Target above, add it to your Nuget package and then import this targets file in the project file via the install.ps1 script. The install.ps1 would be similar to (although I haven't tested this, it may need some tweaks):
param($rootPath, $toolsPath, $package, $project)
# Add targets file to .csproj
$TargetsFile = 'AddToOutput.targets'
$path = [System.IO.Path]
$ProjectDirectory = $path::GetDirectoryName($project.FileName)
$TargetsPath = [System.IO.Path]::Combine($toolsPath, $TargetsFile)
Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
$MSBProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($project.FullName) |
Select-Object -First 1
$ProjectUri = New-Object -TypeName Uri -ArgumentList "file://$($project.FullName)"
$TargetUri = New-Object -TypeName Uri -ArgumentList "file://$TargetsPath"
$RelativePath = $ProjectUri.MakeRelativeUri($TargetUri) -replace '/','\'
$ExistingImports = $MSBProject.Xml.Imports |
Where-Object { $_.Project -like "*\$TargetsFile" }
if ($ExistingImports) {
$ExistingImports |
ForEach-Object {
$MSBProject.Xml.RemoveChild($_) | Out-Null
}
}
$MSBProject.Xml.AddImport($RelativePath) | Out-Null
$project.Save()
Upvotes: 0