Visual Studio 2010 有一个发布命令,允许您将 Web 应用程序项目发布到文件系统位置。我想在我的 TeamCity 构建服务器上执行此操作,因此我需要使用解决方案运行程序或 msbuild 执行此操作。我尝试使用 Publish 目标,但我认为这可能适用于 ClickOnce:
msbuild Project.csproj /t:Publish /p:Configuration=Deploy
我基本上想做一个 Web 部署项目所做的事情,但没有插件。我需要它来编译 WAP,删除任何不需要执行的文件,执行任何 web.config transformations,并将输出复制到指定位置。
我的解决方案,基于 Jeff Siver 的回答
<Target Name="Deploy">
<MSBuild Projects="$(SolutionFile)"
Properties="Configuration=$(Configuration);DeployOnBuild=true;DeployTarget=Package"
ContinueOnError="false" />
<Exec Command=""$(ProjectPath)\obj\$(Configuration)\Package\$(ProjectName).deploy.cmd" /y /m:$(DeployServer) -enableRule:DoNotDeleteRule"
ContinueOnError="false" />
</Target>
我主要是在没有自定义 msbuild 脚本的情况下工作。以下是相关的 TeamCity 构建配置设置:
Artifact paths: %system.teamcity.build.workingDir%\MyProject\obj\Debug\Package\PackageTmp Type of runner: MSBuild (Runner for MSBuild files) Build file path: MyProject\MyProject.csproj Working directory: same as checkout directory MSBuild version: Microsoft .NET Framework 4.0 MSBuild ToolsVersion: 4.0 Run platform: x86 Targets: Package Command line parameters to MSBuild.exe: /p:Configuration=Debug
这将编译、打包(使用 web.config 转换)并将输出保存为工件。唯一缺少的是将输出复制到指定位置,但这可以在另一个具有工件依赖项的 TeamCity 构建配置或使用 msbuild 脚本中完成。
更新
这是一个 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.Configuration
、env.ProjectName
和 env.DeployServiceUrl
的参数。 MSBuild 运行器具有构建文件路径,并且参数自动传递(您不必在命令行参数中指定它们)。
您也可以从命令行运行它:
msbuild build.xml /p:Configuration=Staging;ProjectName=MyProject;DeployServiceUrl=http://staging-server/MSDeployAgentService
使用 VS 2012 中引入的部署配置文件,您可以使用以下命令行进行发布:
msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0
有关参数 see this 的更多信息。
/p:VisualStudioVersion
参数的值取决于您的 Visual Studio 版本。维基百科有一个 table of Visual Studio releases and their versions。
/p:VisualStudioVersion=?
的值是多少?
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 而不是发布文件夹中的所有文件:(`
/p:VisualStudioVersion=15
。我不确定这是否与您的文件复制问题有关。
我想出了这样的解决方案,对我很有用:
msbuild /t:ResolveReferences;_WPPCopyWebApplication /p:BuildingProject=true;OutDir=C:\Temp\build\ Test.csproj
秘诀是 _WPPCopyWebApplication 目标。
error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project
。取出那部分导致部署而不部署任何视图
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
。有解决方案吗?
我不知道 TeamCity,所以我希望这对你有用。
我发现最好的方法是使用 MSDeploy.exe。这是 Microsoft 运行的 WebDeploy 项目的一部分。您可以下载位 here。
使用 WebDeploy,您可以运行命令行
msdeploy.exe -verb:sync -source:contentPath=c:\webApp -dest:contentPath=c:\DeployedWebApp
这与 VS Publish 命令的作用相同,只将必要的位复制到部署文件夹。
使用 VisualStudio 2012 有一种无需发布配置文件即可处理主题的方法。您可以使用参数传递输出文件夹。它适用于“publishUrl”参数中的绝对路径和相对路径。您可以使用 VS100COMNTOOLS,但是您需要覆盖 VisualStudioVersion 才能使用来自 %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets
的目标“WebPublish”。使用 VisualStudioVersion 10.0,此脚本将成功且没有输出 :)
更新:我已经设法在仅安装了 Windows SDK 7.1 的构建服务器上使用此方法(机器上没有 Visual Studio 2010 和 2012)。但我必须按照以下步骤使其工作:
使用 Simmo 答案 (https://stackoverflow.com/a/2907056/2164198) 将注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7\10.0 设置为“C:\Program Files\ Microsoft Visual Studio 10.0\"(根据需要使用您的路径)将文件夹 %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%
发现了两种不同的解决方案,它们的工作方式略有不同:
1. 此解决方案的灵感来自 alexanderb [link] 的答案。不幸的是,它对我们不起作用——一些 dll 没有复制到 OutDir。我们发现将 ResolveReferences
替换为 Build
目标可以解决问题 - 现在所有必要的文件都已复制到 OutDir 位置。
msbuild /target:Build;_WPPCopyWebApplication /p:Configuration=Release;OutDir=C:\Tmp\myApp\ MyApp.csproj
2. 第一个解决方案效果很好,但不如我们预期的那样。我们希望拥有 Visual Studio IDE 中的发布功能——即只有应该发布的文件才会被复制到输出目录中。正如已经提到的第一个解决方案将更多文件复制到 OutDir - 然后将发布的网站存储在 _PublishedWebsites/{ProjectName}
子文件夹中。以下命令解决了这个问题 - 只有发布的文件将被复制到所需的文件夹。所以现在您有了可以直接发布的目录 - 与第一个解决方案相比,您将节省一些硬盘空间。
msbuild /target:Build;PipelinePreDeployCopyAllFilesToOneFolder /p:Configuration=Release;_PackageTempDir=C:\Tmp\myApp\;AutoParameterizationWebConfigConnectionStrings=false MyApp.csproj
自动参数化WebConfigConnectionStrings=false
关联
您必须设置环境
<网站名称>
<域>
并参考我的博客。(抱歉帖子是韩语)
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 -有效解决方案配置的名称 ::::-CreatePackageOnPublish -True :: -False :: ::-DeployIisAppPath -<网站名称>/<文件夹> :: ::-MsDeployServiceUrl -您要使用的 MSDeploy 安装位置 :: ::-MsDeployPublishMethod -WMSVC(Web 管理服务) :: -RemoteAgent :: :: -AllowUntrustedCertificate(与自签名 SSL 证书一起使用)-True :: -False :: ::-UserName ::-Password SETLOCAL IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" SET FXPath="% SystemRoot%\Microsoft.NET\Framework\v2.0.50727" 如果存在 "%SystemRoot%\Microsoft.NET\Framework\v3.5" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v3.5" 如果存在"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319" SET FXPath="%System Root%\Microsoft.NET\Framework\v4.0.30319" SET targetFile=
这是我的工作批次
发布我的网站.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
,因为 .Net Framework 文件夹中的 MsBuild.exe
不起作用。
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 而不是我想要的文件结构。它出什么问题了? :(
您可以通过以下代码发布具有所需路径的解决方案,这里 PublishInDFolder 是具有我们需要发布的路径的名称(我们需要在下图中创建它)
You can create publish file like this
在批处理文件(.bat)中添加以下 2 行代码
@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
这是我的批处理文件
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
为了生成发布输出,请提供另外一个参数。 msbuild example.sln /p:publishprofile=profilename /p:deployonbuild=true /p:configuration=debug/或任何
您可以使用此命令通过发布配置文件发布 Web 应用程序。
msbuild SolutionName.sln /p:DeployOnBuild=true /p:PublishProfile=PublishProfileName
此示例发布配置文件可以创建版本号位于网络路径中 AssemblyInfo.cs 文件中的发布 zip 文件(使用 PowerShell 命令创建 zip 文件并删除其他已发布文件是可选的)。
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<Major>0</Major>
<Minor>1</Minor>
<Build>2</Build>
<Publish>C:\</Publish>
<publishUrl>$(Publish)</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
<Target Name="GetBuildUrl">
<PropertyGroup> <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs'))</In>
<TargetPath>\\NetworkPath\ProjectName</TargetPath>
<Pattern>^\s*\[assembly: AssemblyVersion\(\D*(\d+)\.(\d+)\.(\d+)\.(\d+)</Pattern>
<Major>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</Major>
<Minor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[2].Value)</Minor>
<Build>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[3].Value)</Build>
<Sub>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[4].Value)</Sub>
<Publish>$(TargetPath)\$(Major).$(Minor).$(Build).$(Sub)\</Publish>
<publishUrl Condition=" '$(Publish)' != '' ">$(Publish)</publishUrl>
<publishUrl Condition=" '$(Publish)' == '' and '$(LastUsedBuildConfiguration)'!='' ">$(LastUsedBuildConfiguration)</publishUrl>
</PropertyGroup>
</Target>
<Target Name="BeforeBuild" DependsOnTargets="GetBuildUrl">
<Message Importance="High" Text="|" />
<Message Importance="High" Text=" ================================================================================================" />
<Message Importance="High" Text=" BUILD INFO " />
<Message Importance="High" Text=" Version [$(Major).$(Minor).$(Build)] found in [$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs] " />
<Message Importance="High" Text=" Build will be saved to [$(publishUrl)] " />
<Message Importance="High" Text=" =================================================================================================" />
<Message Importance="High" Text="|" />
</Target>
<Target Name="Zip" BeforeTargets="AfterBuild">
<Exec Command="PowerShell -command Compress-Archive -Path $(Publish) -DestinationPath $(Publish)Release.zip" />
<Exec Command="PowerShell -command Remove-Item -Recurse -Force $(Publish) -Exclude Release.zip" />
</Target>
</Project>
不定期副业成功案例分享
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。 )