96

我有使用 VS2010 创建的 ac# .Net 4.0 项目,现在可以使用 VS2012 访问。

我正在尝试仅将所需文件从本网站发布到目标位置(C:\builds\MyProject[Files])

我的文件结构: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

我正在通过 MSBuild 运行以下命令:

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

这是 FileSystemDebug.pubxml 中的 xml

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

产生的行为是:

  • 在此处创建一个 zip 文件: ./ProjectRoot/obj/Debug/Package/ MyProject.zip
  • 没有部署到<publishUrl>C:\builds\MyProject\</publishUrl>WTF
  • 创建的 zip 文件是猪的早餐,其中包含应用程序不需要的文件。

当我通过 Visual Studio 运行此发布配置文件时,会在 * C:\builds\MyProject*处创建一个文件夹,其中包含我想要的确切工件。

如何从 msbuild 获得这个简单的结果?

4

8 回答 8

57

仅供参考:我在使用 Visual Studio 2015 时遇到了同样的问题。经过数小时的尝试,我现在可以使用msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile.

我必须编辑我的 .csproj 文件才能使其正常工作。它包含这样的一行:

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

我将这一行更改如下:

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

(我将 10.0 更改为 14.0,不确定是否有必要。但我肯定必须删除条件部分。)

于 2016-01-22T09:45:02.087 回答
45

在这里找到答案: http ://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild

Visual Studio 2010 具有出色的新 Web 应用程序项目发布功能,让您只需单击一个按钮即可轻松发布您的 Web 应用程序项目。在幕后,Web.config 转换和包构建是由导入到项目文件中的大量 MSBuild 脚本完成的(位于:C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft .Web.Publishing.targets)。不幸的是,该脚本非常复杂、凌乱且没有文档记录(文件中还有一些拼写错误且大多无用的注释)。该文件的大流程图和一些关于如何挂钩的文档会很好,但似乎很遗憾缺乏(或者至少我找不到它)。

不幸的是,这意味着通过命令行执行发布比它需要的更不透明。我对这方面的文档缺乏感到惊讶,因为现在很多商店都使用持续集成服务器,有些甚至进行自动化部署(VS2010 发布功能可以帮助很多),所以我会认为启用这个(很容易!)将是该功能的一个相当主要的要求。

无论如何,在研究了几个小时的 Microsoft.Web.Publishing.targets 文件并将我的头撞在试错墙上之后,我已经设法弄清楚 Visual Studio 似乎是如何执行其神奇的一键“发布到文件系统”和“构建部署包”功能。我将介绍一些 MSBuild 脚本,所以如果您不熟悉 MSBuild,我建议您查看这个速成课程 MSDN 页面。

发布到文件系统

VS2010 Publish To File System 对话框 Publish to File System 花了我一段时间才弄清楚,因为我预计 MSBuild 会发生一些合理的使用。相反,VS2010 做了一些非常奇怪的事情:它调用 MSBuild 执行一种半部署,在项目的 obj 文件夹中准备 Web 应用程序的文件,然后它似乎手动复制这些文件(即在 MSBuild 之外)进入您的目标发布文件夹。这确实是一种糟糕的行为,因为 MSBuild 旨在复制文件(以及其他与构建相关的东西),所以如果整个过程只是 VS2010 调用的一个 MSBuild 目标,而不是手动复制的目标,那将是有意义的。

这意味着通过命令行上的 MSBuild 执行此操作并不像使用特定目标调用项目文件并设置一些属性那么简单。您需要做 VS2010 应该做的事情:自己创建一个执行半部署的目标,然后将结果复制到目标文件夹。要编辑您的项目文件,请在 VS2010 中右键单击项目并单击 Unload Project,然后再次右键单击并单击 Edit。向下滚动,直到找到导入 Web 应用程序目标的 Import 元素(Microsoft.WebApplication.targets;此文件本身导入前面提到的 Microsoft.Web.Publishing.targets 文件)。在这一行下面,我们将添加我们的新目标,称为 PublishToFileSystem:

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

这个目标取决于 PipelinePreDeployCopyAllFilesToOneFolder 目标,这是 VS2010 在手动复制之前调用的目标。在 Microsoft.Web.Publishing.targets 中进行的一些挖掘表明,调用此目标会导致项目文件被放置到属性 _PackageTempDir 指定的目录中。

我们在目标中调用的第一个任务是 Error 任务,我们在其上设置了一个条件,以确保该任务仅在未设置 PublishDestination 属性时发生。如果您忘记指定 PublishDestination 属性,这将捕获您并错误生成构建。然后我们调用 MakeDir 任务来创建该 PublishDestination 目录(如果它尚不存在)。

然后我们定义一个名为 PublishFiles 的项目,它代表在 _PackageTempDir 文件夹下找到的所有文件。然后调用复制任务,将所有这些文件复制到发布目标文件夹。Copy 元素的 DestinationFiles 属性有点复杂。它执行项目的转换并将它们的路径转换为以 PublishDestination 文件夹为根的新路径(查看 Well-Known Item Metadata 以了解这些 %()s 的含义)。

要从命令行调用此目标,我们现在可以简单地执行此命令(显然更改项目文件名和属性以适合您):

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
于 2013-04-26T23:43:14.947 回答
19

尝试上述所有答案后仍然遇到问题(我使用 Visual Studio 2013)。没有任何内容复制到发布文件夹。

问题是,如果我使用单个项目而不是解决方案运行 MSBuild,我必须添加一个指定 Visual Studio 版本的附加参数:

/p:VisualStudioVersion=12.0

12.0是针对VS2013的,替换成你使用的版本。一旦我添加了这个参数,它就可以工作了。

完整的命令行如下所示:

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

我在这里找到了它:

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

他们说:

如果指定单个项目而不是解决方案,则必须添加指定 Visual Studio 版本的参数。

于 2016-05-10T09:32:49.223 回答
12

在我看来,您的发布配置文件没有被使用,并且正在做一些默认打包。Microsoft Web Publish 目标执行您上面所做的所有操作,它根据配置选择正确的目标。

我在 TeamCity MSBuild 步骤中的工作没有问题,但我确实指定了配置文件的显式路径,您只需要按名称调用它,而不需要 .pubxml(例如 FileSystemDebug)。只要在您的标准文件夹中就可以找到它。

例子:

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

请注意,这是使用 Microsoft Web Publish 目标的 Visual Studio 2012 版本完成的,通常位于“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web”。查看使用的特定部署类型目标的部署文件夹

于 2015-03-27T11:32:03.070 回答
4

实际上,我将您的所有答案合并到我自己的解决方案中,如何解决上述问题:

  1. 我根据需要创建 pubxml 文件
  2. 然后我将所有参数从 pubxml 文件复制到我自己的 msbuild.exe 参数列表“/p:foo=bar”
  3. 我扔掉了 pubxml 文件

结果是这样的:

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

于 2019-06-03T12:42:26.663 回答
3

仅供参考:在构建服务器上运行同样的问题(安装了 msbuild 15 的 Jenkins,在 .NET Core 2.1 Web 项目上从 VS 2017 驱动)。

在我的情况下,使用 msbuild 的“发布”目标忽略了配置文件。

所以我的 msbuild 命令开始于:

msbuild /t:restore;build;publish

这正确触发了发布过程,但“/p:PublishProfile=FolderProfile”的组合或变体无法选择我想要使用的配置文件(“FolderProfile”)。

当我停止使用发布目标时:

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

我(愚蠢地)认为这没什么区别,但是一旦我使用了 DeployOnBuild 开关,它就正确地选择了配置文件。

于 2019-01-08T14:56:21.967 回答
1

首先检查可以发布解决方案(项目)的开发人员 PC 的 Visual Studio 版本。如图所示适用于 VS 2013

 /p:VisualStudioVersion=12.0

添加上面的命令行以指定应该构建项目的 Visual Studio 版本。正如之前的答案,当我们试图只发布一个项目而不是整个解决方案时,可能会发生这种情况。

所以完整的代码是这样的

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" "C:\Program Files (x86)\Jenkins\workspace\Jenkinssecondsample\MVCSampleJenkins\MVCSampleJenkins.csproj" /T:Build;Package /p :Configuration=DEBUG /p:OutputPath="obj\DEBUG" /p:DeployIisAppPath="Default Web Site/jenkinsdemoapp" /p:VisualStudioVersion=12.0

于 2017-10-30T19:57:57.830 回答
0

从项目文件夹运行

msbuild /p:DeployOnBuild=true /p:PublishProfile="release-file.pubxml" /p:AspnetMergePath="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools" / p:配置=发布

这负责 web.config Transform 和 AspnetMergePath

于 2021-01-10T13:40:14.330 回答