wake-up-neo.com

Verwenden von msbuild zum Ausführen eines Dateisystem-Veröffentlichungsprofils

Ich habe ein c # .NET 4.0-Projekt, das mit VS2010 erstellt wurde und jetzt mit VS2012 aufgerufen wird.

Ich versuche, nur die benötigten Dateien von dieser Website an einem Zielort zu veröffentlichen (C:\builds\MyProject [Files])

Meine Dateistruktur: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Eigenschaften/PublishProfiles/FileSystemDebug.pubxml

Ich führe folgendes über MSBuild aus:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj/p: DeployOnBuild = true /p:PublishProfile=

Hier ist die XML in FileSystemDebug.pubxml

<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>C:\builds\MyProject\</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>

Das resultierende Verhalten ist:

  • eine ZIP-Datei wird hier erstellt: ./ProjectRoot/obj/Debug/Package/MyProject.Zip
  • Für<publishUrl>C:\builds\MyProject\</publishUrl>WTF wird nichts bereitgestellt
  • bei der erstellten Zip-Datei handelt es sich um ein Schweinefrühstück mit vielen Dateien, die für die Anwendung nicht benötigt werden.

Wenn ich dieses Veröffentlichungsprofil über Visual Studio starte, wird ein Ordner unter * C:\builds\MyProject * erstellt und enthält die genauen Artefakte, die ich möchte.

Wie bekomme ich dieses einfache Ergebnis von msbuild?

74
P. Roe

Zu Ihrer Information: Ich hatte das gleiche Problem mit Visual Studio 2015. Nach vielen Stunden des Versuchs kann ich jetzt msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile ausführen.

Ich musste meine .csproj-Datei bearbeiten, damit sie funktioniert. Es enthielt eine Zeile wie diese:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" 
  Condition="false" />

Ich habe diese Zeile wie folgt geändert:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" />

(Ich habe 10.0 auf 14.0 geändert, nicht sicher, ob dies notwendig ist. Aber ich musste den Zustandsteil unbedingt entfernen.)

38
johanv

Die Antwort hier gefunden: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Visual Studio 2010 bietet großartige neue Veröffentlichungen für Webanwendungsprojekte Funktionen, mit denen Sie Ihr Web-App-Projekt einfach mit einem .__ veröffentlichen können. Klicken Sie auf eine Schaltfläche. Hinter den Kulissen die Umwandlung von Web.config und Die Paketerstellung erfolgt durch ein umfangreiches MSBuild-Skript, das importiert wird in Ihre Projektdatei (zu finden unter: C:\Programme (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets) . Leider ist das Skript sehr kompliziert, unordentlich und undokumentiert (andere als oft falsch geschrieben und meist nutzlos Kommentare in der Datei). Ein großes Flussdiagramm dieser Datei und einige Eine Dokumentation darüber, wie man sich einhakt, wäre Nizza, scheint jedoch leider fehlt (oder zumindest kann ich es nicht finden).

Leider bedeutet dies, dass die Veröffentlichung über die Befehlszeile durchgeführt wird ist viel undurchsichtiger als es sein muss. Ich war überrascht von dem Mangel der Dokumentation in diesem Bereich, weil heutzutage viele Geschäfte eine .__ verwenden. Continuous Integration Server und einige führen sogar eine automatisierte Bereitstellung durch (womit die VS2010-Veröffentlichungsfunktionen sehr helfen könnten), so dass ich hätte gedacht, dass dies (leicht!) möglich gewesen wäre, eine ziemlich Hauptanforderung für die Funktion.

Nach dem Graben durch die Microsoft.Web.Publishing.targets stundenlang feilen und meinen Kopf gegen die Wand der Versuchs- und Irrtümer schlagen, Ich habe herausgefunden, wie es scheint, dass Visual Studio seine Klicken Sie einfach auf "Im Dateisystem veröffentlichen" und "Build Deployment ". Paket ”-Funktionen. Ich werde mich ein bisschen mit MSBuild-Scripting beschäftigen, also Wenn Sie nicht mit MSBuild vertraut sind, sollten Sie sich diesen Absturz ansehen Kurs MSDN-Seite.

Im Dateisystem veröffentlichen

Das Dialogfeld "VS2010 - Publizieren im Dateisystem" Das Publizieren im Dateisystem nahm. eine Weile zu verraten, weil ich mit einer vernünftigen Verwendung von MSBuild .__ gerechnet hatte. vorkommen Stattdessen macht VS2010 etwas sehr Unheimliches: Es ruft .__ auf. auf MSBuild, um eine Art halbem Einsatz durchzuführen, der das Web vorbereitet App-Dateien im obj-Ordner Ihres Projekts, dann scheint es ein Handbuch zu sein Kopie dieser Dateien (dh außerhalb von MSBuild) in Ihre Zielveröffentlichung Mappe. Das ist wirklich verrücktes Verhalten, da MSBuild auf .__ ausgelegt ist. kopiere Dateien (und andere Build-bezogene Dinge), damit es sinnvoll ist wenn der gesamte Prozess nur ein MSBuild-Ziel war, das VS2010 .__ aufgerufen hat. auf, kein Ziel, dann eine manuelle Kopie.

Dies bedeutet, dass dies über MSBuild in der Befehlszeile nicht wie .__ erfolgt. Sie können einfach Ihre Projektdatei mit einem bestimmten Ziel und .__ aufrufen. einige Eigenschaften einstellen. Sie müssen tun, was VS2010 haben sollte done: Erstellen Sie selbst ein Ziel, das die Teilbereitstellung ausführt, und anschließend kopiert die Ergebnisse in den Zielordner. Um Ihre Projektdatei zu bearbeiten, Klicken Sie mit der rechten Maustaste auf das Projekt in VS2010 und klicken Sie auf Projekt entladen und dann auf Klicken Sie erneut mit der rechten Maustaste und klicken Sie auf Bearbeiten. Scrollen Sie nach unten, bis Sie das .__ gefunden haben. Importelement, das die Webanwendungsziele importiert (Microsoft.WebApplication.targets; diese Datei importiert selbst die zuvor erwähnte Datei Microsoft.Web.Publishing.targets). Unterhalb In dieser Zeile fügen wir unser neues Ziel namens PublishToFileSystem hinzu:

<Target Name="PublishToFileSystem"
        DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
    <Error Condition="'$(PublishDestination)'==''"
           Text="The PublishDestination property must be set to the intended publishing destination." />
    <MakeDir Condition="!Exists($(PublishDestination))"
             Directories="$(PublishDestination)" />

    <ItemGroup>
        <PublishFiles Include="$(_PackageTempDir)\**\*.*" />
    </ItemGroup>

    <Copy SourceFiles="@(PublishFiles)"
          DestinationFiles="@(PublishFiles->'$(PublishDestination)\%(RecursiveDir)%(Filename)%(Extension)')"
          SkipUnchangedFiles="True" />
</Target>

Dieses Ziel hängt von der .__ ab. PipelinePreDeployCopyAllFilesToOneFolder-Ziel. Dies ist das Ziel von VS2010 ruft an, bevor es manuell kopiert wird. Einige graben sich in Microsoft.Web.Publishing.targets zeigt, dass der Aufruf dieses Ziels .__ verursacht. die Projektdateien, die in dem von .__ angegebenen Verzeichnis abgelegt werden sollen. property _PackageTempDir.

Die erste Task, die wir in unserem Ziel aufrufen, ist die Error-Task, auf die Wir haben eine Bedingung aufgestellt, die sicherstellt, dass die Aufgabe nur dann ausgeführt wird, wenn Die PublishDestination-Eigenschaft wurde nicht festgelegt. Das wird dich erwischen und Fehler beim Build, falls Sie vergessen haben, das .__ anzugeben. PublishDestination-Eigenschaft Wir rufen dann die MakeDir-Task auf, um .__ zu erstellen. das PublishDestination-Verzeichnis, falls es noch nicht existiert.

Wir definieren dann ein Element namens PublishFiles, das alle .__ darstellt. Dateien, die unter dem Ordner _PackageTempDir gefunden werden. Die Kopieraufgabe lautet dann aufgerufen, wodurch alle diese Dateien in den Ordner "Publish Destination" kopiert werden . Das DestinationFiles-Attribut im Copy-Element ist etwas komplex; Es führt eine Transformation der Elemente durch und konvertiert ihre Pfade in new Pfade, die im Ordner PublishDestination verwurzelt sind (überprüfen Sie bekannte Bekannte Element-Metadaten, um zu sehen, was diese% () bedeuten).

Um dieses Ziel von der Befehlszeile aus aufzurufen, können Sie jetzt einfach .__ ausführen. diesen Befehl (offensichtlich ändern Sie den Namen und die Eigenschaften der Projektdatei ):

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
39
P. Roe

Ich hatte immer noch Probleme, nachdem ich alle Antworten ausprobiert hatte (ich verwende Visual Studio 2013). Es wurde nichts in den Veröffentlichungsordner kopiert.

Der Haken war, dass ich, wenn ich MSBuild mit einem einzelnen Projekt anstelle einer Lösung ausführte, einen zusätzlichen Parameter eingeben muss, der die Visual Studio-Version angibt:

/p:VisualStudioVersion=12.0

12.0 ist für VS2013, ersetzen Sie es mit der von Ihnen verwendeten Version. Sobald ich diesen Parameter hinzugefügt habe, hat es einfach funktioniert.

Die vollständige Befehlszeile sieht folgendermaßen aus:

MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0

Ich habe es hier gefunden:

http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment

Sie geben an:

Wenn Sie anstelle einer Lösung ein einzelnes Projekt angeben, müssen Sie einen Parameter hinzufügen, der die Visual Studio-Version angibt.

18
felix-b

Es sieht für mich so aus, als würde Ihr Veröffentlichungsprofil nicht verwendet und einige Standardpakete verwendet. Die Microsoft Web Publish-Ziele erledigen alles, was Sie oben tun. Sie wählen die richtigen Ziele basierend auf der Konfiguration aus.

Ich habe keine Probleme mit dem TeamCity MSBuild-Schritt, aber ich habe einen expliziten Pfad zum Profil angegeben. Sie müssen es nur mit dem Namen ohne .pubxml (z. B. FileSystemDebug) aufrufen. Es wird so lange gefunden, wie es sich im Standardordner befindet.

Beispiel:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug

Beachten Sie, dass dies mit den Visual Studio 2012-Versionen der Microsoft Web Publish-Ziele durchgeführt wurde, die sich normalerweise unter "C:\Programme (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web" befinden. Überprüfen Sie den Bereitstellungsordner nach den spezifischen verwendeten Zieltypen

11
GregS

Zu Ihrer Information: Gleiches Problem bei der Ausführung auf einem Build-Server (Jenkins, auf dem msbuild 15 installiert ist und von VS 2017 in einem .NET Core 2.1-Webprojekt gesteuert wird).

In meinem Fall war es die Verwendung des "Publish" -Ziels mit msbuild, das das Profil ignorierte. 

Mein msbuild-Befehl begann also mit:

msbuild /t:restore;build;publish

Dies löste den Veröffentlichungsprozess korrekt aus, aber es funktionierte niemals eine Kombination oder Variation von "/ p: PublishProfile = FolderProfile", um das gewünschte Profil auszuwählen ("FolderProfile").

Wenn ich das Veröffentlichungsziel nicht mehr verwendet habe:

msbuild /t:restore;build /p:DeployOnBuild=true /p:PublishProfile=FolderProfile

Ich dachte (dumm), dass es keinen Unterschied machen würde, aber sobald ich den DeployOnBuild-Switch verwendet habe, hat er das Profil richtig erkannt.

1
From Orbonia

Eigentlich habe ich alle Ihre Antworten zu meiner eigenen Lösung zusammengeführt, um das obige Problem zu lösen:

  1. Ich erstelle die pubxml-Datei nach meinen Wünschen
  2. Dann kopiere ich alle Parameter aus der pubxml-Datei in meine eigene Parameterliste "/ p: foo = bar" für msbuild.exe
  3. Ich werfe die pubxml-Datei weg

Das Ergebnis ist wie folgt:

msbuild /t:restore /t:build /p:WebPublishMethod=FileSystem /p:publishUrl=C:\builds\MyProject\ /p:DeleteExistingFiles=True /p:LastUsedPlatform="Any CPU" /p:Configuration=Release

1
Rainer

Überprüfen Sie zunächst die Visual Studio-Version des Entwickler-PCs, auf der die Lösung (Projekt) veröffentlicht werden kann. wie gezeigt ist für VS 2013

 /p:VisualStudioVersion=12.0

fügen Sie die obige Befehlszeile hinzu, um anzugeben, welche Art von Visual Studio-Version das Projekt erstellen soll. Als vorherige Antworten kann dies passieren, wenn wir versuchen, nur ein Projekt und nicht die gesamte Lösung zu veröffentlichen.

0
shammakalubo