2013-12-18 9 views
25

Als ich den Code eincheckte, erstellte TFS 2013 die Lösung automatisch. Es ist in lokalen VS 2013 in Ordnung, aber in TFS fehlgeschlagen.Build auf TFS 2013 fehlgeschlagen, aber in Ordnung lokal

Hier ist die Zusammenfassung.

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) 

Antwort

53

Ihre TFS 2013 Build-Server verwendet MSBuild 12,0 wo CodeTasksFactory exists in Microsoft.Build.Tasks.v12.0.dll statt Microsoft.Build.Tasks.v4.0.dll.

Im Idealfall sollten Sie folgendes tun:

1) Öffnen Sie die Datei NuGet.targets: C: \ Builds \ 1 \ xxxx \ FTP-Prozessor (neu) \ src.nuget \ nuget.targets

2) Identifizieren Sie die Aufgabe, die auf die alte DLL verweist.

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

3) Dann zukunftssicher es etwa so:

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

Sie haben die Tatsache gefunden, ich kann die Datei nuget.targets ändern. Aber müssen wir den ToolsVersion-Wert in der csproj-Datei ändern? Eigentlich benutze meine lokale Maschine VS 2013, mein TFS verwendet die alte Version. –

+0

Sie könnten den Wert in Ihrer .csproj-Datei ändern, aber eine andere Option besteht darin, diese mit dem Toolswitch zu überschreiben, wenn Sie msbuild.exe aufrufen. http://msdn.microsoft.com/en-us/library/bb383985.aspx – Nicodemeus

+0

@ Zenuka, ich werde aktualisieren, danke. – Nicodemeus

2

Nach vielen Recherchen und dem Versuch, ein paar "Hacks" auszuprobieren, habe ich die genaue Mechanik der Nuget-Wiederherstellung verstanden. Es stellt sich heraus, dass sich alles seit nugget 2.7+ geändert hat und Sie nicht länger den Ordner ".nuget" und die dazugehörigen nuget.exe und nuget.target

hinzufügen müssen. Um meinen Build-Prozess zu beheben und den neuesten empfohlenen Ansatz zu verwenden , ich habe folgendes:

  • Verschieben nuget.config mit SLN-Datei gleichen Ordnerpfad
  • Delete ".nuget" Ordner vollständig
  • löschen Referenzen in SLN-Datei
  • in diesen Ordner zu sein Löschen Sie die folgenden Zeilen aus einer beliebigen .csproj-Datei

-

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

-

Dies könnte einige Zeit dauern, wenn Ihr Projekt Lösung viele Dateien oder Sie arbeiten an vielen Projekten mit Visual Studio 2013 und zuvor.

Die gute Nachricht ist, gibt es ein Powershell-Skript ist, das die oben rekursiv auf einen beliebigen Ordner gilt:

Kurz gesagt, kehrt es „Nuget Paketwiederherstellung aktivieren“, so dass Die neuere Paketwiederherstellungsmethode funktioniert.

In Visual Studio 2013 wurde die automatische Paketwiederherstellung Teil der IDE (und des TFS-Erstellungsprozesses). Diese Methode ist zuverlässiger als die ältere integrierte Msbuild-Paketwiederherstellung. Es ist nicht erforderlich, dass Sie nugget.exe für jede Lösung eingecheckt haben und keine zusätzliche Msbuild-Ziele benötigen. Wenn Sie jedoch die Dateien haben, die sich auf die alte Methode zur Zurückschreibung von Paketen in Ihrem Projekt beziehen, wird Visual Studio automatische Paketwiederherstellung überspringen. (Dieses Verhalten wird sich wahrscheinlich bald ändern , hoffentlich).

können Sie dieses Skript verwenden nuget.exe, nuget.targets und alle Projekt und Lösung Verweise auf nuget.targets zu entfernen, so dass Sie Vorteil der automatischen Paketwiederherstellung erfolgen kann. Es automatisiert mehr oder weniger den hier beschriebenen Prozess .

Es wird durch das Verzeichnis, aus dem Sie das Skript ausführen, recurse und tun es zu Lösungen, die irgendwo da sein können. Sei vorsichtig und viel Spaß! (Nicht verantwortlich für alles, was bricht)

Ein paar gute Links zum Thema:

0

hatte ich ein ähnliches Problem. Wir sind gezwungen, das ältere Msbuild zu verwenden, das mit dem Framework geliefert wird, und nicht die v14-Version, die mit Visual Studio 2015 ausgeliefert wird, da wir alten Delphi.net-Code erstellen. Unsere vcxproj-Dateien lösen ein automatisches Codeanalyseziel aus, das eine Aufgabe hat, die auf Microsoft.Build.Tasks.v12.0.dll beruht. Ich konnte diese Aufgabe überschreiben, indem ich sie in den oberen Teil von vcxproj kopiere und einfügen und den Pfad zur DLL anpassen. Die ursprüngliche Aufgabe finden Sie unter "C: \ Programme (x86) \ MSBuild \ Microsoft \ VisualStudio \ v14.0 \ CodeAnalysis \ Microsoft.CodeAnalysis.Targets". Mit anderen Worten, Sie können die Problemaufgabe in Ihrem Projekt möglicherweise überschreiben.

<?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>