使用msbuild执行文件系统发布配置文件

P. *_*Roe 79 c# msbuild publish visual-studio

我有用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>
Run Code Online (Sandbox Code Playgroud)

结果是:

  • 这里创建一个zip文件:./ ProjectRoot/obj/Debug/Package/MyProject.zip
  • 没有任何东西部署到<publishUrl>C:\builds\MyProject\</publishUrl>WTF
  • 创建的zip文件是猪早餐,并且包含应用程序不需要的文件.

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

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

joh*_*anv 43

仅供参考:我在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" />
Run Code Online (Sandbox Code Playgroud)

我改变了这一行如下:

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

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

  • 请注意`$(MSBuildToolsVersion)`在路径中策略使用正确的VS版本:`<Import Project ="$(MSBuildExtensionsPath32)\ Microsoft\VisualStudio\v $(MSBuildToolsVersion)\ WebApplications\Microsoft.WebApplication.targets "Condition ="false"/>`.这在VS2015 Update 1上对我有用. (3认同)

P. *_*Roe 41

在这里找到答案: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发布到文件系统对话框发布到文件系统花了我一段时间来坚持,因为我期望MSBuild的一些合理使用正在发生.相反,VS2010做了一件非常奇怪的事情:它调用MSBuild执行一种半部署,在项目的obj文件夹中准备Web应用程序的文件,然后它似乎手动复制这些文件(即在MSBuild之外)进入目标发布文件夹.这真的很糟糕,因为MSBuild旨在复制文件(以及其他与构建相关的东西),所以如果整个过程只是VS2010调用的一个MSBuild目标,而不是目标,那么它是有意义的.

这意味着在命令行上通过MSBuild执行此操作并不像使用特定目标调用项目文件和设置某些属性那么简单.你需要做VS2010应该做的事情:自己创建一个执行半部署的目标然后将结果复制到目标文件夹.要编辑项目文件,请在VS2010中右键单击项目,然后单击"卸载项目",再次右键单击并单击"编辑".向下滚动,直到找到导入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>
Run Code Online (Sandbox Code Playgroud)

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

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

然后我们定义一个名为PublishFiles的Item,它表示在_PackageTempDir文件夹下找到的所有文件.然后调用复制任务,将所有这些文件复制到"发布目标"文件夹.Copy元素上的DestinationFiles属性有点复杂; 它执行项目的转换并将其路径转换为以PublishDestination文件夹为根的新路径(查看已知项目元数据以查看那些%()的含义).

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

msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
Run Code Online (Sandbox Code Playgroud)

  • @АнтонКурьян:链接往往会在一段时间后消失,这就是为什么stackoverflow.com上的问题和答案应该始终是自包含的,而不依赖于外部资源. (4认同)
  • 我无法理解新目标的代码片段(它显示01 02 03 ...).你能编辑一下吗? (3认同)
  • 我同意fan711.虽然,解决方案是在链接上描述的 - 然后复制它的是什么? (2认同)

fel*_*x-b 18

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

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

/p:VisualStudioVersion=12.0
Run Code Online (Sandbox Code Playgroud)

12.0适用于VS2013,替换为您使用的版本.一旦我添加了这个参数,它就可以了.

完整的命令行如下所示:

MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0
Run Code Online (Sandbox Code Playgroud)

我在这里找到了它:

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

他们说:

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


Gre*_*egS 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

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


Rai*_*ner 5

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

  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