Я хочу настроить свое решение VS таким образом, чтобы в конце сборки устанавливаемые файлы были заархивированы для упрощения распространения. Это должно работать либо при локальной сборке, либо при сборке TFS. Это настроено следующим образом:
- Есть один проект (MyApp.Packaging), который не содержит кода, а только сценарий MSBUILD .targets.
- В проекте есть ссылки на все другие проекты, поэтому сборки будут последними (подтверждено просмотром порядка сборки проекта)
- Сценарий сборки содержит следующее, чтобы идентифицировать и заархивировать (с помощью задачи ZIP в MSBUILD Community Tasks) EXE и DLL в два разных пакета (есть другой код для извлечения номера версии из файла version.txt с помощью задач сообщества MSBUILD - опущен для ясность)
<!-- Set package name and input/output folders --> <PropertyGroup> <PackageName>MyAppService</PackageName> <BuildTargetFolder>$(TargetDir)</BuildTargetFolder> <PackageOutputFolder>$(OutDir)</PackageOutputFolder> </PropertyGroup> <!-- Set location of files --> <ItemGroup> <MyAppBinaries Include="$(BuildTargetFolder)*.exe$(BuildTargetFolder)*.dll;" Exclude="$(BuildTargetFolder)MyApp.Packaging.dll" /> <MyAppOtherFiles Include="$(SolutionDir)MyApp.Packaging\InstallService.bat;$(SolutionDir)MyApp.Packaging\UnInstallService.bat;$(BuildTargetFolder)MyApp.HostService.exe.config" /> <MyAppContracts Include="$(BuildTargetFolder)MyApp.Common.DataContext.dll;$(BuildTargetFolder)MyApp.Common.Shared.dll" /> </ItemGroup> <!-- After building (in Release mode only), build the installation package --> <Target Name="AfterBuild"> <CallTarget Targets="BuildPackage" Condition="'$(Configuration)'=='Release'" /> </Target> <!-- Build the package --> <Target Name="BuildPackage"> <!-- Package for installing the MyApp Service --> <Zip Files="@(MyAppBinaries);@(MyAppOtherFiles)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_$(Major).$(Minor).$(Revision)_Install.zip" /> <!-- Package for MyApp Contracts --> <Zip Files="@(MyAppContracts)" Flatten="True" WorkingDirectory="$(MSBuildProjectDirectory)" ZipFileName="$(PackageOutputFolder)\$(PackageName)_MyAppContracts_$(Major).$(Minor).$(Revision)_Install.zip" /> </Target>
Файлы ZIP создаются в месте размещения TFS, когда TFS выполняет сборку, или в папке bin проекта упаковки для локальной сборки.
Второй ZIP-файл (содержащий 2 библиотеки DLL) всегда создается нормально при локальной сборке и сборке TFS.
Проблема в том, что когда TFS выполняет сборку, первый ZIP-файл не содержит EXE и только 2 из 23 DLL (и все 3 файла, идентифицированные MyAppOtherFiles). Когда сборка выполняется локально (и сначала очищается папка bin проекта Packaging), первый ZIP-файл не содержит EXE или DLL, а только 2 файла .bat, идентифицированных MyAppOtherFiles.
Если я изменю BuildTargetFolder с $ (TargetDir) на $ (OutDir), я получу тот же результат.
В определении сборки TFS используется неизмененный шаблон по умолчанию.
Это как если бы, когда TFS выполняет сборку, проект упаковки является третьим, а не последним проектом, который нужно собрать, поэтому архивируются только 2 библиотеки DLL. Однако решение, зарегистрированное в TFS, точно такое же, как то, что я создаю локально, и в этом случае кажется, что сценарий не может видеть НИКАКИХ двоичных файлов. Если локальная сборка выполняется снова (без очистки папки bin проекта Packaging), тогда ZIP-архивы содержат все необходимые файлы, но это, очевидно, потому, что после 1-й сборки папка bin теперь содержит EXE и все библиотеки DLL.
Также сбивает с толку то, что при сборке TFS файл MyApp.HostService.exe.config (который создается сборкой) заархивирован, но не MyApp.HostService.exe. И почему 2-й ZIP всегда создается нормально, если он содержит библиотеки DLL, которые пропускаются в 1-м ZIP ????? Я попытался поменять местами порядок создания ZIP-архивов, но это не имеет значения!
Что я могу сделать, чтобы архивирование всегда выполнялось после сборки всех проектов как в локальной, так и в TFS-сборке?
Спасибо