2016-02-03 3 views
0

У меня есть собственный пакет nuget, содержащий некоторые собственные DLL-файлы.Nuget скопировать родную dll в вывод

Когда я создаю проект, который ссылается на пакет nuget, я хочу, чтобы все файлы из пакета nuget были скопированы в выходной каталог.

Как создать такой nuget pacakge, который копирует файлы в выходной каталог?

Я пытался использовать Baseclass.Contrib.Nuget.Output, но я не могу заставить его работать на моем сервере сборки (TFS 2013):

C: \ Строит \ 1 \ MyProject \ BUILDNAME \ SRC \ MyProject \ Пакеты \ Baseclass.Contrib.Nuget.Output.2.1.0 \ build \ net40 \ Baseclass.Contrib.Nuget.Output.targets (73): Исходный файл для этой компиляции можно найти по адресу: «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): ошибка произошел во время компиляции. ошибка CS1705: сборка «Microsoft.Build.Utilities.Core, Version = 14.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a» использует «Microsoft.Build.Framework, Version = 14.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a», который имеет более высокую версию, чем ссылка сборки 'Microsoft.Build.Framework, Version = 12.0.0.0, Culture = нейтрально, PublicKeyToken = b03f5f7f11d50a3a'

C: \ Строит \ 1 \ MyProject \ BUILDNAME \ src \ MyProject \ Packages \ Baseclass.Contrib.Nuget.Output.2.1.0 \ build \ net40 \ Baseclass.Contrib.Nuget.Output.targets (73): Задача «PackageFilter» не найдена. Проверьте следующее: 1.) Имя задачи в файле проекта совпадает с именем класса задачи. 2.) Класс задачи является «общедоступным» и реализует интерфейс Microsoft.Build.Framework.ITask. 3.) Задача правильно объявлена ​​в файле проекта или в файлах * .tasks, расположенных в каталоге «C: \ Program Files (x86) \ MSBuild \ 14.0 \ bin \ amd64».

C: \ Строит \ 1 \ MyProject \ BUILDNAME \ SRC \ MyProject \ Packages \ Baseclass.Contrib.Nuget.Output.2.1.0 \ построить \ net40 \ Baseclass.Contrib.Nuget .Output.targets (73): во время компиляции произошла ошибка. ошибка CS1705: сборка «Microsoft.Build.Utilities.Core, Version = 14.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a» использует «Microsoft.Build.Framework, Version = 14.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a», который имеет более высокую версию, чем ссылка сборки 'Microsoft.Build.Framework, Version = 12.0.0.0, Culture = нейтрально, PublicKeyToken = b03f5f7f11d50a3a'

C: \ Строит \ 1 \ MyProject \ BUILDNAME \ src \ MyProject \ Packages \ Baseclass.Contrib.Nuget.Output.2.1.0 \ build \ net40 \ Baseclass.Contrib.Nuget.Output.targets (73): Задача «PackageFilter» не найдена. Проверьте следующее: 1.) Имя задачи в файле проекта совпадает с именем класса задачи. 2.) Класс задачи является «общедоступным» и реализует интерфейс Microsoft.Build.Framework.ITask. 3.) Задача правильно объявлена ​​в файле проекта или в поле *.файлы задач, расположенные в каталоге «C: \ Program Files (x86) \ MSBuild \ 14.0 \ bin \ amd64».

+0

Почему не устанавливая CopyLocal ваших ссылочных сборок в файле проекта? – wonko79

+0

, потому что они не являются сборками, и на них не ссылаются. – Liero

+0

Вы можете сделать это с любым файлом, добавленным в ваш проект. Но тогда свойство называется Copy to Output Directory. Тогда это также сработает для локальных сборок. – wonko79

ответ

0

Для этого вы можете написать логику MSBuild. Я не проверял этот код, но вы могли бы использовать что-то подобное следующему (с тонкой настройкой):

<Target Name="AfterBuild"> 
    <ItemGroup> 
    <NugetDlls Include="$(SolutionDir)\packages\mypackage\**\*.dll" /> 
    </ItemGroup> 
    <Copy SourceFiles="@(NugetDlls)" DestinationFolder="$(OutputPath)" /> 
</Target> 

Вы даже можете автоматизировать это изменение с помощью NuGet с помощью start.ps1 PowerShell script in the Tools directory. В этом случае я создам отдельный файл .targets с указанным выше объектом MSBuild, добавлю его в пакет Nuget, а затем импортируем этот файл цели в файл проекта с помощью скрипта install.ps1. Install.ps1 была бы подобна (хотя я не проверял это, возможно, потребуется несколько щипков):

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() 
+0

Редактирование файлов проекта немного громоздко для поддержания. «mypackage» обычно всегда содержит номер версии. Возможно, использование mypackage * будет работать, но вы всегда должны помнить, что вы возились с файлом проекта :) – wonko79

+1

Вы можете использовать подстановочные знаки (например, «mypackage * \ ** \ *. Dl»), чтобы игнорировать номера версий на пакете, но я согласен его громоздким. Если это веб-приложение, вы можете поместить этот код в файл [projectName] .wpp.targets, чтобы сделать его более заметным. В конце концов, я думаю, что это решение является вашим лучшим вариантом за пределами ссылок на библиотеки DLL. – chief7

+0

Мне нужно создать пакет nuget, который просто работает. Я не могу заставить людей редактировать их .csproj, чтобы использовать мой пакет. – Liero