如何使用msbuild发布Web?


216

Visual Studio 2010具有“发布”命令,该命令允许您将Web应用程序项目发布到文件系统位置。我想在TeamCity构建服务器上执行此操作,因此需要使用解决方案运行程序或msbuild进行操作。我尝试使用发布目标,但我认为这可能适用于ClickOnce:

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

我基本上想做一个Web部署项目完全一样的事情,但是没有外接程序。我需要它来编译WAP,删除执行所需的所有文件,执行任何web.config转换并将输出复制到指定位置。

我的解决方案,基于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我目前正在VS 2008中使用Web部署项目(正如我在对该问题的回答中提到的那样),但我想尝试自动化VS 2010的发布功能。
jrummell 2010年


2
只需对脚本进行一点修改:您将$(ProjectPath)用于部署脚本,但您真正想要的是$(ProjectDir),否则最终会得到.csproj \ obj
Troy Hunt 2010年

2
从VS2012开始,这要容易得多:stackoverflow.com/a/13947667/270348
RobSiklos 2014年

Answers:


137

我大多数情况下都不需要自定义msbuild脚本。以下是相关的TeamCity构建配置设置:

工件路径:%system.teamcity.build.workingDir%\ MyProject \ obj \ Debug \ Package \ PackageTmp 
运行程序类型:MSBuild(用于MSBuild文件的运行程序) 
生成文件路径:MyProject \ MyProject.csproj 
工作目录:与结帐目录相同 
MSBuild版本:Microsoft .NET Framework 4.0 
MSBuild工具版本:4.0 
运行平台:x86 
目标:包装 
MSBuild.exe的命令行参数:/ p:Configuration = Debug

这将进行编译,打包(通过web.config转换),并将输出保存为工件。唯一缺少的是将输出复制到指定的位置,但是可以在另一个带有工件依赖项或使用msbuild脚本的TeamCity构建配置中完成。

更新资料

这是一个msbuild脚本,它将编译,打包(通过web.config转换)并将输出复制到我的登台服务器

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

您还可以从PropertyGroup标记中删除SolutionName和ProjectName属性,并将它们传递给msbuild。

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

更新2

由于此问题仍然引起大量访问,因此我认为有必要使用当前使用Web Deploy的脚本(也称为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>

在TeamCity的,我有一个名为参数env.Configurationenv.ProjectNameenv.DeployServiceUrl。MSBuild运行程序具有构建文件路径,并且参数会自动传递(您不必在命令行参数中指定它们)。

您也可以从命令行运行它:

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

2
谢谢-这也可以直接从Powershell很好地工作(格式化的道歉-注释中没有回车符):&msbuild“ $ solution” / p:“ Configuration = $ configuration”; &msbuild“ $ project” / t:Package / p:“ Configuration = $ configuration; _PackageTempDir = $ outputfolder”
zcrar70

我从第一个Update中尝试了该示例,而且Package目标似乎也依赖于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.提及它是因为您写到第二个更新使用WebDeploy,这可能意味着第一个更新尚未使用WebDeploy。)
chiccodoro

@jrummell:我想将Visual Studio Web项目从TeamCity部署到远程Windows服务器。我该怎么办。我是一个初学者,不知道该怎么做
Nevin Raj Victor

1
我可以使它在带有Web应用程序项目的TeamCity上工作,但是我还有一个旧版绑定的网站项目,我还需要发布(作为软件包)然后使用MSDeploy。如果我在VS2013中发布,则会得到一个部署程序包,但cmd行中的MSBuild不会创建一个。有什么想法吗?
KnowHowSolutions 2015年

1
我在此没有看到任何发布个人资料。应该指定发布配置文件,以便应用正确的web.config转换。更新:没关系...该功能在发布此文章后的两年后才引入。这可能仍然有效。此线程的后续文章介绍了如何使用命令行中的发布配置文件进行发布。
Triynko

84

使用VS 2012中引入的部署配置文件,可以使用以下命令行发布:

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

有关参数的更多信息,请参见this

/p:VisualStudioVersion参数的值取决于您的Visual Studio版本。Wikipedia有一张Visual Studio版本及其版本的表


6
使用VS2012 .NET 3.5,这不适用于部署到文件系统。它只是构建而不进行部署。
杰伊·沙利文2014年

2
您的/p:VisualStudioVersion=11.0挽救了我的命。我对/ v2013使用/p:VisualStudioVersion=12.0,它的工作正常。
Seyed Morteza Mousavi 2014年

/p:VisualStudioVersion=?VS 2017 的价值是什么?
Nishant

创建了构建脚本 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 ......但是仍然仅获得DLL而不是像发布文件夹中那样的所有文件:(`
Nishant

@Nishant对于VS 2017,请使用/p:VisualStudioVersion=15。我不确定这是否与您的文件复制问题有关。
克里斯

38

我想出了这样的解决方案,对我非常有用:

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

秘诀是_WPPCopyWebApplication目标。


1
什么是_WPPCopyWebApplication,我如何使用它MSBbuild xml配置文件/
Johnny_D 2013年

4
使用VS2012 .NET 3.5,我得到了错误error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project。删除该部分导致部署而没有部署任何视图
Jay Sullivan 2014年

您可能需要使用其他/p:VisualStudioVersion=12.0来调用它,因为构建使用来自c:\ program files(x86)\ msbuild \ microsoft \ visualstudio \ VERSION \ Webapplication \ Microsoft.WebApplication.targets的目标,因此也许使用没有正确目标的旧版本。
Jim Wolff 2014年

@FRoZeN我尝试使用MSBuild作为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。这给我一个错误 MSBUILD : error MSB1008: Only one project can be specified. Switch: WebSite/New。有解决方案吗?
Nevin Raj Victor

1
@NevinRajVictor该错误很可能是因为DeployIisAppPath值中有空格。您需要将值放在引号中。例如/ p:DeployIisAppPath =“默认网站/新”
shiitake

27

我不了解TeamCity,所以希望这对您有用。

我发现最好的方法是使用MSDeploy.exe。这是Microsoft运行的WebDeploy项目的一部分。您可以在此处下载这些位。

使用WebDeploy,您可以运行命令行

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

这与VS Publish命令具有相同的作用,仅将必要的位复制到部署文件夹。


这看起来很有希望。但是,看来管理服务仅在Server 2008上可用。我的登台服务器(我要在其中自动执行部署)正在运行Windows 7 Pro。
jrummell 2010年

2
该产品有两块。正确集成到IIS中的片段需要Server 2008。我让它在用于部署的Server 2003机器上运行。
杰夫·西弗

我已经在MSDeploy上做了一些阅读。我已安装它并在我的登台服务器上工作,谢谢!我可以从MSBuild脚本运行MSDeploy吗?
jrummell 2010年

1
与VS Publish命令的哪种配置相同?哪种发布方法-文件系统或其他?它是否使用MyProject.Publish.xml文件来确定要复制哪些文件?
安东尼

1
我只是试了一下,但它与VS Publish的功能不同。它和XCopy一样,包括所有源文件。
Louis Somers

13

使用VisualStudio 2012,可以在不发布配置文件的情况下处理主题。您可以使用参数传递输出文件夹。它适用于'publishUrl'参数中的绝对路径和相对路径。您可以使用VS100COMNTOOLS,但是您需要覆盖VisualStudioVersion才能从中使用目标“ WebPublish” %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets。使用VisualStudioVersion 10.0时,此脚本将成功,但不输出:)

更新:我设法在仅安装Windows SDK 7.1的构建服务器上使用此方法(计算机上没有安装Visual Studio 2010和2012)。但是我必须按照以下步骤操作:

  1. 使用Simmo回答(https://stackoverflow.com/a/2907056/2164198)使Windows SDK 7.1在计算机上为最新版本
  2. 将注册表项HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \ SxS \ VS7 \ 10.0设置为“ C:\ Program Files \ Microsoft Visual Studio 10.0 \”(使用适当的路径)
  3. 从我的开发人员机器复制文件夹%ProgramFiles%\ MSBuild \ Microsoft \ VisualStudio \ v11.0来构建服务器

脚本:

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%

感谢您提供此解决方案,这就是我一直在寻找的:具有文件系统部署功能的WebPublish选项。
woohoo

12

找到了两种工作方式略有不同的不同解决方案:

1.该解决方案的灵感来自亚历山大[link]的答案。不幸的是,它对我们不起作用-一些dll没有复制到OutDir。我们发现ResolveReferencesBuild目标替换可以解决问题-现在将所有必需的文件复制到OutDir位置。

msbuild / target:Build; _WPPCopyWebApplication / p:Configuration =发布; OutDir = C:\ Tmp \ myApp \ MyApp.csproj
该解决方案的缺点是OutDir不只包含要发布的文件。

2.第一个解决方案效果不错,但不像我们预期的那样。我们希望具有Visual Studio IDE中的发布功能-即,仅应发布的文件将被复制到Output目录。如前所述,第一个解决方案将更多文件复制到OutDir中-然后将要发布的网站存储在_PublishedWebsites/{ProjectName}子文件夹中。以下命令解决了这一问题-仅将要发布的文件复制到所需的文件夹中。因此,现在您拥有可以直接发布的目录-与第一种解决方案相比,您可以节省硬盘驱动器上的空间。

msbuild / target:Build; PipelinePreDeployCopyAllFilesToOneFolder / p:配置=发布; _PackageTempDir = C:\ Tmp \ myApp \; AutoParameterizationWebConfigConnectionStrings = false MyApp.csproj
AutoParameterizationWebConfigConnectionStrings=false参数将确保连接字符串不会被当作特殊工件处理,并且会正确生成-有关更多信息,请参见link


您的选项2帮助我无缝摆脱了过时的_CopyWebApplication。升级到VS 2015后,您拯救了我的构建服务器。出色的研究。感激。
it3xl

您的选择#2非常适合我的构建脚本。
AnthonyVO

3

您必须设置环境

  • <网站名称>
  • <域>

并引用我的博客。(抱歉帖子是韩语)

  • 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

这是我的批处理文件

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
如果您可以详细说明答案,那就太好了。您的批处理文件如何准确解决OP的问题?谢谢!
路易斯·克鲁兹

1

这是我的工作批

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%

请注意,我在服务器上安装了Visual Studio以便能够运行,MsBuild.exe因为MsBuild.exe.Net Framework文件夹中的文件夹不起作用。


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 ......但是仍然只获得DLL而不是我想要的文件结构。它出什么问题了?:(
Nishant

1

您可以通过下面的代码使用所需的路径发布解决方案,这里PublishInDFolder是具有我们需要发布的路径的名称(我们需要在下面的图片中创建此路径)

您可以像这样创建发布文件

在批处理文件(.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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.