2009-03-10 2 views
10

У меня нормальный SLN-файл, и я компилирую его с помощью msbuild в командной строке. Я делаю это:msbuild SLN и все еще получать отдельные выходные данные проекта?

C: \ slndir> MSBuild/р: OutDir = C: \ slnbin \

И сваливает все в C: \ slnbin, для веб-сайтов, которые получают развернуты C, за исключением: \ slnbin_PublishedWebsites \.

Что бы я хотел, это не только удалить все двоичные файлы в каталоге bin, но также иметь в каждой исполняемой программе свою собственную «развернутую» папку, похожую на то, что получает каждый веб-сайт.

Так, например, если у меня есть следующие проекты: - Common - Lib1 - Service1 - Lib2 - Service2

я тусклый, чтобы получить:

C:\slnbin\ // Everything 
    C:\slbin\Deploy\Service1 // Common, Lib1, Service1 
    C:\slbin\Deploy\Service2 // Common, Lib2, Service2 

Я пытался делать такие как «msbuild/p: OutDir = C: \ slnbin \ $ (ProjectName)», но он просто рассматривает его как литерал и создает фактический поддиск «$ ProjectName».

Предпочтительно, мне не пришлось бы изменять каждый отдельный проект и так далее.

Возможно ли это? Легко?

ответ

13

Как сказал Джон Сондерс, вам необходимо иметь файл MSBuild, который обрабатывает этот процесс.

Вот пример использование MSBuild Community Tasks: GetSolutionProjects, которые получают проекты для данного решения

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Package"> 

    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 

    <!-- Specify here, the solution you want to compile--> 
    <ItemGroup> 
    <Solution Include="C:\slndir\solution.sln"/> 
    </ItemGroup> 

    <PropertyGroup> 
    <Platform>AnyCPU</Platform> 
    <Configuration>Debug</Configuration> 

    <!-- Your deployment directory --> 
    <DeployDir>C:\slbin\Deploy</DeployDir> 
    </PropertyGroup> 

    <!-- Gets the projects composing the specified solution --> 
    <Target Name="GetProjectsFromSolution"> 
    <GetSolutionProjects Solution="%(Solution.Fullpath)"> 
     <Output ItemName="ProjectFiles" TaskParameter="Output"/> 
    </GetSolutionProjects> 
    </Target> 

    <Target Name="CompileProject" DependsOnTargets="GetProjectsFromSolution"> 
    <!-- 
     Foreach project files 
     Call MSBuild Build Target specifying the outputDir with the project filename. 
    --> 
    <MSBuild Projects="%(ProjectFiles.Fullpath)" 
      Properties="Platform=$(Platform); 
      Configuration=$(Configuration); 
      OutDir=$(DeployDir)\%(ProjectFiles.Filename)\" 
      Targets="Build"> 
    </MSBuild> 
    </Target> 
</Project> 
+1

Это отлично работает для нас. Один вопрос - когда вы вызываете MSBuild, проходящий Projects = "% (ProjectFiles.Fullpath)", является MSBuild достаточно умным, чтобы только строить каждый проект один раз? Например, если у вас есть foo.dll, который находится в решении, и на него ссылаются 4 других проекта, будет ли он строить foo.dll один раз, или 4 раза, или 5 раз? –

+2

«В отличие от использования Exec Task для запуска MSBuild.exe, эта задача использует тот же процесс MSBuild для создания дочерних проектов. Список уже построенных целей, которые можно пропустить, разделяется между родительскими и дочерними сборками. быстрее, потому что не создается новый процесс MSBuild ». Поэтому я думаю, foo.dll будет строить один раз, но я не уверен. –

+2

Что нужно для создания командной строки? –

1

Вам нужно будет сделать это «вручную». Создайте главный файл проекта MSBUILD, который создает решение, а затем копирует все выходные решения, где он им нужен. Это (примерно), как это делает Visual Studio Team Build.

+1

Так что я не могу использовать тот факт, что csproj файлы знать все их зависимость? Было ли это означать, что я должен поддерживать зависимости в двух местах (csprojs и msbuild)? – MichaelGG

Смежные вопросы