Come pubblicare Web con msbuild?


216

Visual Studio 2010 ha un comando Pubblica che consente di pubblicare il progetto di applicazione Web in un percorso del file system. Vorrei farlo sul mio server di build TeamCity, quindi devo farlo con il runner della soluzione o msbuild. Ho provato a utilizzare la destinazione Pubblica, ma penso che potrebbe essere per ClickOnce:

msbuild Project.csproj /t:Publish /p:Configuration=Deploy

In pratica, voglio fare esattamente ciò che fa un progetto di distribuzione Web, ma senza il componente aggiuntivo. Ne ho bisogno per compilare il WAP, rimuovere tutti i file non necessari per l'esecuzione, eseguire qualsiasi trasformazione web.config e copiare l'output in una posizione specifica.

La mia soluzione , basata sulla risposta di Jeff Siver

<Target Name="Deploy">
    <MSBuild Projects="$(SolutionFile)" 
             Properties="Configuration=$(Configuration);DeployOnBuild=true;DeployTarget=Package" 
             ContinueOnError="false" />
    <Exec Command="&quot;$(ProjectPath)\obj\$(Configuration)\Package\$(ProjectName).deploy.cmd&quot; /y /m:$(DeployServer) -enableRule:DoNotDeleteRule" 
          ContinueOnError="false" />
</Target>


@SnOrfus Attualmente sto utilizzando i progetti di distribuzione Web in VS 2008 (come ho già detto nella mia risposta a quella domanda) ma mi piacerebbe provare invece ad automatizzare la funzione Pubblica di VS 2010.
jrummell,

Questa domanda sembra utile stackoverflow.com/questions/1983575/...
jrummell

2
Solo un piccolo emendamento al tuo script: stai usando $ (ProjectPath) per lo script deploy ma vuoi davvero $ (ProjectDir) altrimenti finirai con .csproj \ obj
Troy Hunt,

2
A partire con VS2012, questo è molto più facile: stackoverflow.com/a/13947667/270348
RobSiklos

Risposte:


136

L'ho fatto funzionare principalmente senza uno script msbuild personalizzato. Ecco le impostazioni di configurazione build TeamCity pertinenti:

Percorsi artefatto:% system.teamcity.build.workingDir% \ MyProject \ obj \ Debug \ Package \ PackageTmp 
Tipo di runner: MSBuild (Runner per file MSBuild) 
Percorso del file di build: MyProject \ MyProject.csproj 
Directory di lavoro: uguale alla directory di pagamento 
Versione MSBuild: Microsoft .NET Framework 4.0 
Versione MSBuild Tools: 4.0 
Esegui piattaforma: x86 
Obiettivi: pacchetto 
Parametri della riga di comando su MSBuild.exe: / p: Configuration = Debug

Questo compilerà, impacchetterà (con trasformazione web.config) e salverà l'output come artefatti. L'unica cosa che manca è copiare l'output in una posizione specificata, ma ciò potrebbe essere fatto in un'altra configurazione di build di TeamCity con una dipendenza artefatto o con uno script msbuild.

Aggiornare

Ecco uno script msbuild che compilerà, impacchetterà (con trasformazione web.config) e copierà l'output sul mio server di gestione temporanea

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
        <SolutionName>MySolution</SolutionName>
        <SolutionFile>$(SolutionName).sln</SolutionFile>
        <ProjectName>MyProject</ProjectName>
        <ProjectFile>$(ProjectName)\$(ProjectName).csproj</ProjectFile>
    </PropertyGroup>

    <Target Name="Build" DependsOnTargets="BuildPackage;CopyOutput" />

    <Target Name="BuildPackage">
        <MSBuild Projects="$(SolutionFile)" ContinueOnError="false" Targets="Rebuild" Properties="Configuration=$(Configuration)" />
        <MSBuild Projects="$(ProjectFile)" ContinueOnError="false" Targets="Package" Properties="Configuration=$(Configuration)" />
    </Target>

    <Target Name="CopyOutput">
        <ItemGroup>
            <PackagedFiles Include="$(ProjectName)\obj\$(Configuration)\Package\PackageTmp\**\*.*"/>
        </ItemGroup>
        <Copy SourceFiles="@(PackagedFiles)" DestinationFiles="@(PackagedFiles->'\\build02\wwwroot\$(ProjectName)\$(Configuration)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    </Target>
</Project>

Puoi anche rimuovere le proprietà SolutionName e ProjectName dal tag PropertyGroup e passarle a msbuild.

msbuild build.xml /p:Configuration=Deploy;SolutionName=MySolution;ProjectName=MyProject

Aggiornamento 2

Dato che questa domanda riceve ancora molto traffico, ho pensato che valesse la pena aggiornare la mia risposta con il mio script corrente che utilizza Web Deploy (noto anche come MSDeploy).

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <ProjectFile Condition=" '$(ProjectFile)' == '' ">$(ProjectName)\$(ProjectName).csproj</ProjectFile>
    <DeployServiceUrl Condition=" '$(DeployServiceUrl)' == '' ">http://staging-server/MSDeployAgentService</DeployServiceUrl>
  </PropertyGroup>

  <Target Name="VerifyProperties">
    <!-- Verify that we have values for all required properties -->
    <Error Condition=" '$(ProjectName)' == '' " Text="ProjectName is required." />
  </Target>

  <Target Name="Build" DependsOnTargets="VerifyProperties">
    <!-- Deploy using windows authentication -->
    <MSBuild Projects="$(ProjectFile)"
             Properties="Configuration=$(Configuration);
                             MvcBuildViews=False;
                             DeployOnBuild=true;
                             DeployTarget=MSDeployPublish;
                             CreatePackageOnPublish=True;
                             AllowUntrustedCertificate=True;
                             MSDeployPublishMethod=RemoteAgent;
                             MsDeployServiceUrl=$(DeployServiceUrl);
                             SkipExtraFilesOnServer=True;
                             UserName=;
                             Password=;"
             ContinueOnError="false" />
  </Target>
</Project>

In TeamCity, ho parametri denominati env.Configuration, env.ProjectNamee env.DeployServiceUrl. Il runner MSBuild ha il percorso del file di build e i parametri vengono passati automaticamente (non è necessario specificarli nei parametri della riga di comando).

Puoi anche eseguirlo dalla riga di comando:

msbuild build.xml /p:Configuration=Staging;ProjectName=MyProject;DeployServiceUrl=http://staging-server/MSDeployAgentService

2
grazie - funziona anche direttamente da PowerShell (ci scusiamo per la formattazione - nessun ritorno a capo nei commenti): & msbuild "$ solution" / p: "Configuration = $ configuration"; & msbuild "$ project" / t: Package / p: "Configuration = $ configuration; _PackageTempDir = $ outputfolder"
zcrar70

Ho provato l'esempio dal tuo primo aggiornamento e sembra che la Packagedestinazione dipenda anche da WebDeploy: error : Package/Publish task Microsoft.Web.Publishing.Tasks.IsCleanMSDeployPackageNeeded failed to load Web Deploy assemblies. Microsoft Web Deploy is not correctly installed on this machine.(menzionandolo da quando scrivi che il tuo secondo aggiornamento utilizza WebDeploy, il che potrebbe implicare che il primo non utilizzerebbe ancora WebDeploy.)
Chiccodoro

@jrummell: desidero distribuire il mio progetto Web Visual Studio su un server Windows remoto da TeamCity. Cosa dovrei fare. Sono un principiante e non ho idea di cosa fare
Nevin Raj Victor,

1
Sono in grado di farlo funzionare su TeamCity con i progetti di applicazioni Web, ma ho anche un PROGETTO del sito Web legato legacy che devo anche pubblicare (come pacchetto) e quindi utilizzare MSDeploy. Se pubblico in VS2013 ottengo un pacchetto di distribuzione, ma MSBuild dalla riga cmd non ne crea uno. qualche idea?
KnowHowSolutions il

1
Non vedo alcuna menzione del profilo di pubblicazione in questo. Il profilo di pubblicazione deve essere specificato in modo da applicare la trasformazione web.config corretta. Aggiornamento: Nevermind ... questa funzione è stata introdotta 2 anni dopo questo post. Questo probabilmente funziona ancora. Il post successivo in questa discussione mostra come pubblicare con un profilo di pubblicazione dalla riga di comando.
Triynko,

84

Utilizzando i profili di distribuzione introdotti in VS 2012, è possibile pubblicare con la seguente riga di comando:

msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0

Per ulteriori informazioni sui parametri vedere questo .

I valori per il /p:VisualStudioVersionparametro dipendono dalla versione di Visual Studio. Wikipedia ha una tabella con le versioni di Visual Studio e le loro versioni .


6
Utilizzando VS2012 .NET 3.5, questo non ha funzionato per la distribuzione nel file system. Si costruisce semplicemente e non esegue alcuna distribuzione.
Jay Sullivan,

2
il tuo /p:VisualStudioVersion=11.0 mi ha salvato la vita. Uso /p:VisualStudioVersion=12.0 per vs2013 e funziona perfettamente.
Seyed Morteza Mousavi,

Quale sarà il valore /p:VisualStudioVersion=?per VS 2017?
Nishant,

creato lo script di compilazione msbuild test.sln /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=.\build_output1\pub /p:PublishProfile=FolderProfile /p:VisualStudioVersion=11.0 /p:outdir=.\build_output1 ...... Ma ottenendo ancora solo DLL non tutti i file come nella cartella di pubblicazione: (`
Nishant

@Nishant Per VS 2017, utilizzare /p:VisualStudioVersion=15. Non sono sicuro che ciò sia correlato al problema di copia dei file.
Chris

38

Ho trovato una soluzione del genere, funziona benissimo per me:

msbuild /t:ResolveReferences;_WPPCopyWebApplication /p:BuildingProject=true;OutDir=C:\Temp\build\ Test.csproj

La salsa segreta è la destinazione _WPPCopyWebApplication.


1
Che cos'è _WPPCopyWebApplication e come posso usarlo File di configurazione xml MSBbuild /
Johnny_D

4
Utilizzando VS2012 .NET 3.5, ho ottenuto l'errore error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project. La rimozione di quella parte ha portato a uno schieramento senza dispiegare alcun punto di vista
Jay Sullivan,

Potrebbe essere necessario chiamarlo con un /p:VisualStudioVersion=12.0 diverso perché build utilizza le destinazioni da c: \ program files (x86) \ msbuild \ microsoft \ visualstudio \ VERSION \ Webapplication \ Microsoft.WebApplication.targets, quindi forse sta usando un versione precedente che non ha la destinazione corretta.
Jim Wolff,

@FRoZeN Ho provato a utilizzare MSBuild come MSBuild.exe C:\BuildAgent\work\4c7b8ac8bc7d723e\WebService.sln /p:Configuration=Release /p:OutputPath=bin /p:DeployOnBuild=True /p:DeployTarget=MSDeployPublish /p:MsDeployServiceUrl=https://204.158.674.5/msdeploy.axd /p:username=Admin /p:password=Password#321 /p:AllowUntrustedCertificate=True /p:DeployIisAppPath=Default WebSite/New /p:MSDeployPublishMethod=WMSVC. Mi dà un errore MSBUILD : error MSB1008: Only one project can be specified. Switch: WebSite/New. C'è una soluzione per questo?
Nevin Raj Victor,

1
@NevinRajVictor questo errore è probabile perché si dispone di uno spazio nel valore DeployIisAppPath. Dovrai inserire il valore tra virgolette. eg / p: DeployIisAppPath = "Sito Web predefinito / Nuovo"
shiitake,

27

Non conosco TeamCity quindi spero che questo possa funzionare per te.

Il modo migliore che ho trovato per farlo è con MSDeploy.exe. Questo fa parte del progetto WebDeploy gestito da Microsoft. Puoi scaricare i bit qui .

Con WebDeploy, si esegue la riga di comando

msdeploy.exe -verb:sync -source:contentPath=c:\webApp -dest:contentPath=c:\DeployedWebApp

Questo fa la stessa cosa del comando VS Publish, copiando solo i bit necessari nella cartella di distribuzione.


Sembra promettente. Tuttavia, sembra che il servizio di gestione sia disponibile solo sul server 2008. Il mio server di gestione temporanea (dove desidero automatizzare la distribuzione) esegue Windows 7 Pro.
jrummell,

2
Ci sono due pezzi per il prodotto. I pezzi che si integrano direttamente in IIS richiedono Server 2008. Il componente della riga di comando non ha questo requisito; Ce l'ho in esecuzione su una scatola Server 2003 che uso per le distribuzioni.
Jeff Siver,

Ho letto alcune cose su MSDeploy. L'ho installato e funzionante sul mio server di gestione temporanea, grazie! Posso eseguire MSDeploy da uno script MSBuild?
Jrummell,

1
fa la stessa cosa di quale configurazione del comando VS Publish? Quale metodo di pubblicazione - file system o altro? Utilizza il file MyProject.Publish.xml per determinare quali file copiare?
Anthony,

1
Ho appena provato, ma non ha fatto lo stesso di VS Publish. Ha fatto lo stesso di XCopy compresi tutti i file di origine.
Louis Somers,

13

Con VisualStudio 2012 esiste un modo per gestire subj senza pubblicare profili. È possibile passare la cartella di output utilizzando i parametri. Funziona sia con percorso assoluto che relativo nel parametro 'publishingUrl'. È possibile utilizzare VS100COMNTOOLS, tuttavia è necessario sovrascrivere VisualStudioVersion per utilizzare la destinazione "WebPublish" da %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets. Con VisualStudioVersion 10.0 questo script avrà esito positivo senza output :)

Aggiornamento: sono riuscito a utilizzare questo metodo su un server di build con solo Windows SDK 7.1 installato (senza Visual Studio 2010 e 2012 su una macchina). Ma ho dovuto seguire questi passaggi per farlo funzionare:

  1. Rendi Windows SDK 7.1 aggiornato su un computer utilizzando la risposta di Simmo ( https://stackoverflow.com/a/2907056/2164198 )
  2. Impostazione della chiave del Registro di sistema HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \ SxS \ VS7 \ 10.0 su "C: \ Programmi \ Microsoft Visual Studio 10.0 \" (utilizzare il percorso appropriato)
  3. Copia della cartella% ProgramFiles% \ MSBuild \ Microsoft \ VisualStudio \ v11.0 dalla mia macchina sviluppatore per costruire il server

script:

set WORK_DIR=%~dp0
pushd %WORK_DIR%
set OUTPUTS=%WORK_DIR%..\Outputs
set CONFIG=%~1
if "%CONFIG%"=="" set CONFIG=Release
set VSTOOLS="%VS100COMNTOOLS%"
if %VSTOOLS%=="" set "PATH=%PATH%;%WINDIR%\Microsoft.NET\Framework\v4.0.30319" && goto skipvsinit
call "%VSTOOLS:~1,-1%vsvars32.bat"
if errorlevel 1 goto end
:skipvsinit
msbuild.exe Project.csproj /t:WebPublish /p:Configuration=%CONFIG% /p:VisualStudioVersion=11.0 /p:WebPublishMethod=FileSystem /p:publishUrl=%OUTPUTS%\Project
if errorlevel 1 goto end
:end
popd
exit /b %ERRORLEVEL%

Grazie per questa soluzione: questo è quello che stavo cercando: l'opzione WebPublish con la distribuzione del file system.
woohoo,

12

trovato due diverse soluzioni che hanno funzionato in modo leggermente diverso:

1. Questa soluzione si ispira alla risposta di alexanderb [link] . Sfortunatamente non ha funzionato per noi - alcune DLL non sono state copiate nell'OutDir. Abbiamo scoperto che la sostituzione ResolveReferencescon la Builddestinazione risolve il problema: ora tutti i file necessari vengono copiati nella posizione OutDir.

msbuild / target: Build; _WPPCopyWebApplication / p: Configuration = Release; OutDir = C: \ Tmp \ myApp \ MyApp.csproj
Lo svantaggio di questa soluzione era il fatto che OutDir conteneva non solo file per la pubblicazione.

2. La prima soluzione funziona bene ma non come previsto. Volevamo avere la funzionalità di pubblicazione così come è nell'IDE di Visual Studio, ovvero solo i file che dovrebbero essere pubblicati verranno copiati nella directory di output. Come è già stato menzionato, la prima soluzione copia molti più file in OutDir: il sito Web per la pubblicazione viene quindi archiviato in una _PublishedWebsites/{ProjectName}sottocartella. Il seguente comando risolve questo problema: solo i file per la pubblicazione verranno copiati nella cartella desiderata. Quindi ora hai una directory che può essere pubblicata direttamente - rispetto alla prima soluzione risparmierai spazio sul disco rigido.

msbuild / target: Build; PipelinePreDeployCopyAllFilesToOneFolder / p: Configuration = Release; _PackageTempDir = C: \ Tmp \ myApp \; AutoParameterizationWebConfigConnectionStrings = false MyApp.csproj
AutoParameterizationWebConfigConnectionStrings=falseIl parametro garantirà che le stringhe di connessione non verranno gestite come artefatti speciali e verranno generate correttamente - per ulteriori informazioni, consultare il collegamento .


La tua opzione n. 2 mi ha aiutato a sbarazzarmi senza problemi della obsoleta _CopyWebApplication. Hai salvato il mio Build-Server dopo l'aggiornamento a VS 2015. Grande ricerca. Riconoscente.
it3xl

La tua opzione n. 2 era perfetta per il mio script di build.
AnthonyVO,

3

Devi impostare i tuoi ambienti

  • <Nome sito Web>
  • <dominio>

e fare riferimento al mio blog. (mi dispiace, il post era coreano)

  • http://xyz37.blog.me/50124665657
  • http://blog.naver.com/PostSearchList.nhn?SearchText=webdeploy&blogId=xyz37&x=25&y=7

    @ECHO OFF
    :: http://stackoverflow.com/questions/5598668/valid-parameters-for-msdeploy-via-msbuild
    ::-DeployOnBuild -True
    :: -False
    :: 
    ::-DeployTarget -MsDeployPublish
    :: -Package
    :: 
    ::-Configuration -Name of a valid solution configuration
    :: 
    ::-CreatePackageOnPublish -True
    :: -False
    :: 
    ::-DeployIisAppPath -<Web Site Name>/<Folder>
    :: 
    ::-MsDeployServiceUrl -Location of MSDeploy installation you want to use
    :: 
    ::-MsDeployPublishMethod -WMSVC (Web Management Service)
    :: -RemoteAgent
    :: 
    ::-AllowUntrustedCertificate (used with self-signed SSL certificates) -True
    :: -False
    :: 
    ::-UserName
    ::-Password
    SETLOCAL
    
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727"
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v3.5" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v3.5"
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v4.0.30319" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v4.0.30319"
    
    SET targetFile=<web site fullPath ie. .\trunk\WebServer\WebServer.csproj
    SET configuration=Release
    SET msDeployServiceUrl=https://<domain>:8172/MsDeploy.axd
    SET msDeploySite="<WebSite name>"
    SET userName="WebDeploy"
    SET password=%USERNAME%
    SET platform=AnyCPU
    SET msbuild=%FXPath%\MSBuild.exe /MaxCpuCount:%NUMBER_OF_PROCESSORS% /clp:ShowCommandLine
    
    %MSBuild% %targetFile% /p:configuration=%configuration%;Platform=%platform% /p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=False /p:DeployIISAppPath=%msDeploySite% /p:MSDeployPublishMethod=WMSVC /p:MsDeployServiceUrl=%msDeployServiceUrl% /p:AllowUntrustedCertificate=True /p:UserName=%USERNAME% /p:Password=%password% /p:SkipExtraFilesOnServer=True /p:VisualStudioVersion=12.0
    
    IF NOT "%ERRORLEVEL%"=="0" PAUSE 
    ENDLOCAL

1

Questo è il mio file batch

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\Projects\testPublish\testPublish.csproj  /p:DeployOnBuild=true /property:Configuration=Release
if exist "C:\PublishDirectory" rd /q /s "C:\PublishDirectory"
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p C:\Projects\testPublish\obj\Release\Package\PackageTmp -c C:\PublishDirectory
cd C:\PublishDirectory\bin 
del *.xml
del *.pdb

5
Sarebbe bello se tu potessi dettagliare la tua risposta. In che modo esattamente il file batch risolve il problema dell'OP? Grazie!
Luís Cruz,

1

questo è il mio gruppo di lavoro

publish-my-website.bat

SET MSBUILD_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin"
SET PUBLISH_DIRECTORY="C:\MyWebsitePublished"
SET PROJECT="D:\Github\MyWebSite.csproj"


cd /d %MSBUILD_PATH%
MSBuild %PROJECT%  /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=%PUBLISH_DIRECTORY%

Si noti che ho installato Visual Studio sul server per poterlo eseguire MsBuild.exeperché le MsBuild.execartelle in .Net Framework non funzionano.


msbuild test.sln /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=.\build_output1\pub /p:PublishProfile=FolderProfile /p:VisualStudioVersion=11.0 /p:outdir=.\build_output1 ...... Ma ancora ottenere solo DLL non la struttura di file che voglio. Che cosa c'è che non va? :(
Nishant,

1

Puoi pubblicare la soluzione con il percorso desiderato tramite il codice seguente, qui PublishInDFolder è il nome che ha il percorso in cui dobbiamo pubblicare (dobbiamo creare questo nella foto sotto)

È possibile creare file di pubblicazione in questo modo

Aggiungi sotto 2 righe di codice nel file batch (.bat)

@echo OFF 
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsMSBuildCmd.bat"
MSBuild.exe  D:\\Solution\\DataLink.sln /p:DeployOnBuild=true /p:PublishProfile=PublishInDFolder
pause

0

Per generare l'output di pubblicazione, fornire un altro parametro. esempio msbuild.sln / p: publishingprofile = nome profilo / p: deployonbuild = true / p: configuration = debug / o qualsiasi

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.