2012-07-11 6 views
9

Ich versuche, ein MSBuild-Skript zum Erstellen und Extrahieren einer relativ großen Webanwendung für die Bereitstellung zu erstellen. (Wir sprechen hier ein paar tausend Dateien in mehreren Dutzend Verzeichnissen. Es ist so ziemlich eine vererbte, alte Codebase, also kann ich nicht viel dagegen tun.) Der Build selbst läuft gut, aber ich kann es nicht kopieren Dateien an einem Ablageort funktionieren ordnungsgemäß.Kopieren von Build-Ausgabedateien unter Beibehaltung der Verzeichnisstruktur führt zu ungültigen Zeichen im Pfad

Hier ein Ausschnitt zeigt, was ich in der Build-Skript haben:

<PropertyGroup Condition=" '$(UseBuildNumber)' == 'true' "> 
    <ReleaseDirectory>$(ReleaseBaseDirectory)$(ReleaseName)\$(BuildNumber)</ReleaseDirectory> 
</PropertyGroup> 

<ItemGroup> 
    <OutputFiles Include=" 
       $(SourceRoot)**\*.aspx; 
       $(SourceRoot)**\*.dll; 
       $(SourceRoot)**\*.gif; 
       $(SourceRoot)**\*.ascx; 
       " /> 
</ItemGroup> 

<Message Text="Output files ==> @(OutputFiles)" /> 

<Copy 
    SourceFiles="@(OutputFiles)" 
    DestinationFolder="$(ReleaseDirectory)" 
    SkipUnchangedFiles="false" 
    /> 

ich ein paar zusätzliche <Message/> dort gesetzt haben, um sicherzustellen, dass die einzelnen Pfade korrekt erweitern, und beide $(SourceRoot) und $(ReleaseDirectory) in der Tat haben die richtigen Wege. Doch in der Ausgabe, I (vollständigen Pfad der Kürze halber elided) erhalten:

Task "Message" 
    Output files ==> ...\Requirement1866**\*.aspx;...\Requirement1866**\*.dll;...\Requirement1866**\*.gif;...\Requirement1866**\*.ascx 
Done executing task "Message". 

Offensichtlich hat Wildcard Erweiterung nicht durchgeführt wurde, und die folgende Copy dann (vorhersagbar genug) ausfällt. Ich schließe nur einen ein; In der Realität wird dies für jedes der Wildcard-Muster für Dateinamen wiederholt (was wiederum viel mehr sind, als ich oben im Build-Skript-Snippet angegeben habe).

Using "Copy" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". 
Task "Copy" 
    Copying file from "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx". 
    Command: 
    copy /y "*basedir*\Requirement1866**\*.aspx" "*targetdir*\Requirement1866\*buildnumber*\*.aspx" 
d:\Builds\215\BuildType\TFSBuild.proj(120,5): error MSB3021: Unable to copy file "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx". Illegal characters in path. 

gefolgt von:

d:\Builds\215\BuildType\TFSBuild.proj(120,5): error MSB3021: Unable to copy file "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx". Illegal characters in path. 

Die einzige einigermaßen relevant Hit ich googeln diese Copy Task - Illegal characters in path war ganz in meiner Bemühungen gekommen sind, aber ich bin schon ein <ItemGroup> verwenden und das <CreateItem> Beispiel (angepasst) hat überhaupt nicht funktioniert, vorzeitig abgebrochen mit einem Fehler, der besagt, dass TaskParameter unbekannt war (sorry, ich habe nicht die genaue Fehlermeldung vor mir).

Als Notlösung könnte ich die relevanten Dateien aus dem Build-Ausgabeverzeichnis manuell dorthin kopieren, wo ich sie haben möchte, aber ich möchte, dass dieser Prozess automatisiert wird.

Wie kann ich dann mithilfe von MSBuild Dateien, die während des Erstellungsprozesses erstellt werden, in ein Ausgabeverzeichnis kopieren und gleichzeitig die relative Verzeichnisstruktur beibehalten, ohne sie einzeln aufzulisten?

+0

Ich habe keine direkte Antwort, aber ich habe dieses Problem auch schon einmal gesehen. Am Ende habe ich ein PowerShell-Skript geschrieben und es als Post-Build-Aktion bezeichnet. Auch +1 zur Frage, weil es so beeindruckend gut recherchiert ist. Ich freue mich auf die richtige Antwort! – allquixotic

Antwort

20

Grundsätzlich ist ** ein einzelner Pfad-Element und somit muss in der Include Richtlinie entsprechend umgekehrten Schrägstrich-abgrenzen:

<ItemGroup> 
    <OutputFiles Include=" 
       $(SourceRoot)\**\*.aspx; 
       $(SourceRoot)\**\*.dll; 
       $(SourceRoot)\**\*.gif; 
       $(SourceRoot)\**\*.ascx; 
       " /> 
</ItemGroup> 

Man beachte den Unterschied zwischen Angabe z.B. $(SourceRoot)\**\*.aspx im Gegensatz zu den gebrochenen $(SourceRoot)**\*.aspx. Wenn $(SourceRoot) mit einem \ beendet worden wäre, hätte die Wildcard-Erweiterung wahrscheinlich auch zuerst funktioniert.

Zweitens in <Copy/> verwenden %(RecursiveDir):

<Copy 
    SourceFiles="@(OutputFiles)" 
    DestinationFolder="$(ReleaseDirectory)\%(RecursiveDir)" 
    SkipUnchangedFiles="false" 
    /> 

Mit diesen Änderungen ist es so, wie ich es will zu arbeiten scheint: Dateien an den gewünschten Zielverzeichnis kopiert werden, und die Verzeichnisstruktur an der Quelle wird am Zielort beibehalten.

2

Ein weiterer Vorschlag, anstelle von Includes für jeden Dateityp hinzuzufügen, ist es einfach, Excludes hinzuzufügen.

Auf diese Weise enthält die Ausgabe JS, HTML, DHTML und andere Dateitypen, die erforderlich sind.

+0

Jeder Ansatz funktioniert, je nach Bedarf. In meinem speziellen Fall war es wesentlich einfacher aufzuzählen, was ich kopieren wollte, und alles andere einfach auszuschließen. –

Verwandte Themen