首页 文章

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

提问于
浏览
73

我有一个用VS2010创建的c#.Net 4.0项目,现在可以通过VS2012访问 .

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

My file structure: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml

I'm running the following via MSBuild:

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

Here's the xml in FileSystemDebug.pubxml

<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获得这个简单的结果?

5 回答

  • 39

    它看起来像你的发布配置文件没有被使用,并做一些默认包装 . 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” . 查看部署文件夹,了解所使用的特定部署类型目标

  • 0

    在尝试上述所有答案后仍然遇到麻烦(我使用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版本的参数 .

  • 11

    仅供参考:我在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,不确定是否有必要 . 但我肯定要删除条件部分 . )

  • 36

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

    /p:VisualStudioVersion=12.0
    

    添加上面的命令行以指定应该构建项目的Visual Studio版本的类型 . 如前所述,当我们尝试仅发布一个项目而不是整个解决方案时,可能会发生这种情况 .

  • 18

    在这里找到答案: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>
    

    此目标取决于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
    

相关问题