2013-12-18 6 views
25

Po sprawdzeniu kodu, TFS 2013 zbudował rozwiązanie automatycznie. To jest w porządku w lokalnym VS 2013, ale nie powiodło się w TFS.Kompilacja na TFS 2013 nie udała się, ale w porządku lokalnie

Oto podsumowanie.

Summary 
FTPProcessor | Any CPU 
1 error(s), 56 warning(s) 
$/xxxx/NewServiceHost/New-Branch/NewServiceHost/packageRestore.proj - 0 error(s), 0 warning(s) 
$/xxxx/NewServiceHost/New-Branch/GenericWindowsServices.sln - 1 error(s), 56 warning(s) 
C:\Builds\1\xxxx\FTP Processor (New)\src\.nuget\nuget.targets (71): The task factory "CodeTaskFactory" could not be loaded from the assembly "C:\Program Files (x86)\MSBuild\12.0\bin\amd64\Microsoft.Build.Tasks.v4.0.dll". Could not load file or assembly 'file:///C:\Program Files (x86)\MSBuild\12.0\bin\amd64\Microsoft.Build.Tasks.v4.0.dll' or one of its dependencies. The system cannot find the file specified. 
Other Errors 
1 error(s) 
Exception Message: MSBuild error 1 has ended this build. You can find more specific information about the cause of this error in above messages. (type BuildProcessTerminateException) Exception Stack Trace: at System.Activities.Statements.Throw.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation) 

Odpowiedz

53

Twój serwer TFS 2013 build używa MSBuild 12,0 gdzie CodeTasksFactory exists in Microsoft.Build.Tasks.v12.0.dll zamiast Microsoft.Build.Tasks.v4.0.dll.

Idealnie powinno być w następujący sposób:

1) Otwórz plik NuGet.targets: C: \ Buduje \ 1 \ xxxx \ Procesor FTP (Nowe) \ src.nuget \ nuget.targets

2) Wskaż zadanie odwołujące się do starej biblioteki DLL.

<UsingTask AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory" > 
... 

3) Następnie przyszły dowód to tak:

<UsingTask AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll" TaskFactory="CodeTaskFactory" > 
... 
+1

Znalazłeś fakt, mogę zmienić plik nuget.targets. Ale czy potrzebujemy zmienić wartość ToolsVersion w pliku csproj? W rzeczywistości mój lokalny komputer używa VS 2013, mój TFS używa starej wersji. –

+0

Możesz zmienić wartość w pliku .csproj, ale inną opcją jest przesłonięcie tego przy użyciu przełącznika toolsversion podczas wywoływania msbuild.exe. http://msdn.microsoft.com/en-us/library/bb383985.aspx – Nicodemeus

+0

@Zenuka, zaktualizuję, dziękuję. – Nicodemeus

2

Po wielu badaniach i wypróbowaniu kilku "hacków", pojąłem dokładną mechanikę przywracania nugetu. Okazuje się, że wszystko zmieniło się od nugetu 2.7+ i nie trzeba już dołączać folderu ".nuget" i związanych z nim plików nuget.exe i nuget.target

Aby naprawić proces kompilacji i zastosować najnowsze zalecane podejście zrobiłem następujący:

  • Move nuget.config być z .sln plików samej ścieżce folderu
  • Usuń folder ".nuget" całkowicie
  • Usuń odwołania do tego folderu w pliku .sln
  • Usuń następujące linie z dowolnego pliku .csproj

-

<RestorePackages>true</RestorePackages> 
<Import Project="$(SolutionDir)\.nuget\nuget.targets" /> 
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> 

-

Może to zająć trochę czasu, jeśli rozwiązanie projekt ma wiele plików lub pracować na wielu projektach budowanych z Visual Studio 2013 i wcześniej.

Dobrą wiadomością jest to, że skrypt powershell, że wyżej wymienione rekurencyjnie na dowolnym folderze:

W skrócie, to odwraca "Włącz Nuget Pakiet Restore", umożliwiając nowsza metoda przywracania pakietów do pracy.

W Visual Studio 2013 automatyczne przywracanie pakietów stało się częścią IDE (i procesu budowania TFS). Ta metoda jest bardziej niezawodna niż starsze, wbudowane przywracanie pakietów msbuild. Nie wymaga to, aby nuget.exe było zaznaczone w każdym rozwiązaniu i nie wymaga żadnych dodatkowych celów msbuild w postaci . Jeśli jednak masz pliki związane z starą metodę przywracania pakietów w projekcie, Visual Studio będzie pominąć automatyczne przywracanie pakietów. (To zachowanie prawdopodobnie zmieni się wkrótce, mam nadzieję, że tak się stanie).

Można użyć tego skryptu, aby usunąć nuget.exe, nuget.targets, a wszystkie projektu i rozwiązanie odniesienia do nuget.targets więc można wziąć zaletą pakietu Automatic Restore. W mniejszym lub większym stopniu automatyzuje opisany tutaj proces .

Powtarza się przez katalog, z którego uruchamiany jest skrypt, i wykonuje go dla dowolnego rozwiązania, które może znajdować się gdzieś w tym katalogu. Bądź ostrożny i baw się dobrze! (Nie jest odpowiedzialny za wszystko, co łamie)

Kilka dobrych linków na temat:

0

miałem podobny problem. Jesteśmy zmuszeni do używania starszego msbuilda, który pochodzi z ramą, niż wersji v14, która jest dostarczana z visual studio 2015, ponieważ tworzymy stary kod Delphi.net. Nasze pliki vcxproj uruchamiają pewien automatyczny cel analizy kodu, który ma zadanie, które opiera się na Microsoft.Build.Tasks.v12.0.dll. Byłem w stanie zastąpić to zadanie, kopiując i wklejając go w górnej części vcxproj i poprawiając ścieżkę do biblioteki dll. Oryginalne zadanie można znaleźć w "C: \ Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ v14.0 \ CodeAnalysis \ Microsoft.CodeAnalysis.Targets". Innymi słowy, możesz zastąpić zadanie problemu w swoim projekcie.

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

    <!-- override a task which we can't use with the old msbuild --> 
    <UsingTask TaskName="SetEnvironmentVariable" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"> 
    <ParameterGroup> 
     <EnvKey ParameterType="System.String" Required="true" /> 
     <EnvValue ParameterType="System.String" Required="true" /> 
    </ParameterGroup> 
    <Task> 
     <Using Namespace="System" /> 
     <Code Type="Fragment" Language="cs"> 
     <![CDATA[ 
      try { 
       Environment.SetEnvironmentVariable(EnvKey, EnvValue, System.EnvironmentVariableTarget.Process); 
      } 
      catch { 
      } 
     ]]> 
     </Code> 
    </Task> 
    </UsingTask> 
Powiązane problemy