【问题标题】:Using msbuild to execute a File System Publish Profile使用 msbuild 执行文件系统发布配置文件
【发布时间】:2013-04-21 05:24:34
【问题描述】:

我有一个用 VS2010 创建的 c# .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
  • 没有部署到 &lt;publishUrl&gt;C:\builds\MyProject\&lt;/publishUrl&gt; WTF
  • 创建的 zip 文件是猪的早餐,其中包含应用程序不需要的文件。

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

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

【问题讨论】:

    标签: c# visual-studio msbuild publish


    【解决方案1】:

    仅供参考:我在使用 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,不知道有没有必要,但是肯定要去掉条件部分。)

    【讨论】:

    • 带有Condition="false" 的条件导入是为了向后兼容。 VS2010 要求此导入存在,即使它由于虚假条件而被跳过。如果你再看一遍,你会发现 csproj 包含另一个对 $(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets 的导入,它解析为当前版本的 Visual Studio 的目标文件。
    • 注意$(MSBuildToolsVersion) 在路径中的战略使用以说明正确的 VS 版本:&lt;Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(MSBuildToolsVersion)\WebApplications\Microsoft.WebApplication.targets" Condition="false" /&gt;。这在 VS2015 Update 1 上对我有用。
    • 这不适用于 .NET Core 5.0+ 应用程序(非 Web)
    【解决方案2】:

    在这里找到答案: 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)。 不幸的是,剧本非常复杂、凌乱且 无证(除一些经常拼写错误且大多无用的以外) cmets 文件)。该文件的大流程图和一些 关于如何挂钩的文档会很好,但似乎是 遗憾的是缺少(或者至少我找不到)。

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

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

    发布到文件系统

    VS2010 发布到文件系统对话框发布到文件系统采取 我有一段时间要发疯了,因为我希望对 MSBuild 进行一些合理的使用 正在发生。相反,VS2010 做了一些很奇怪的事情:它调用 在 MSBuild 上执行一种准备 Web 的半部署 app 的文件在你项目的 obj 文件夹中,然后它似乎做了一个手册 将这些文件(即 MSBuild 之外)复制到您的目标发布中 文件夹。这真的是很糟糕的行为,因为 MSBuild 旨在 复制文件(和其他与构建相关的东西),所以这很有意义 如果整个过程只是 VS2010 调用的一个 MSBuild 目标 on,不是目标,而是手动复制。

    这意味着在命令行上通过 MSBuild 执行此操作并不像 就像使用特定目标调用您的项目文件一样简单,并且 设置一些属性。你需要做 VS2010 应该做的事情 完成:自己创建一个目标,然后执行半部署 将结果复制到目标文件夹。要编辑您的项目文件, 右键单击VS2010中的项目并单击卸载项目,然后 再次右键单击并单击编辑。向下滚动直到找到 导入 Web 应用程序目标的导入元素 (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。

    我们在目标中调用的第一个任务是错误任务,在这个任务上 我们设置了一个条件,确保任务仅在以下情况下发生 PublishDestination 属性尚未设置。这会抓住你 如果您忘记指定 PublishDestination 属性。然后我们调用 MakeDir 任务来创建 如果 PublishDestination 目录不存在的话。

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

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

    msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:\Temp\Publish" /t:PublishToFileSystem
    

    【讨论】:

    • 我无法理解新目标的代码 sn-p(它显示 01 02 03 ...)。你能编辑一下吗?
    • 我同意fan711。虽然,解决方案是在链接上描述的 - 那么复制它是为了什么?
    • @АнтонКурьян:链接往往会在一段时间后消失,这就是为什么 stackoverflow.com 上的问题和答案应该始终是独立的,而不依赖于外部资源。
    • 结果看起来 MSBuild 根本没有使用发布配置文件,而是在做一个包(也许是默认的?)。您的以下解决方案通过从其部署文件夹(用于文件系统)中选择正确的类型来复制配置文件设置的功能,Microsoft.Web.Publishing.targets 可以处理这些操作。所以看起来你在这里重新发明轮子,而不是解决这个问题。但是如果没有您的 MSBuild 日志,就不能肯定地说。我让我的工作,我的答案中的详细信息
    • GregS 的解决方案对我不起作用。构建正常,但没有文件复制到发布目录
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      在我看来,您的发布配置文件没有被使用,并且正在执行一些默认打包。 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”。查看部署文件夹以了解所使用的特定部署类型目标

      【讨论】:

      • 自几年前发布此内容以来,MS 已经做了很多改进,感谢更新程序?
      【解决方案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

      【讨论】:

        【解决方案6】:

        仅供参考:在构建服务器上运行时遇到同样的问题(安装了 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 开关,它就正确地选择了配置文件。

        【讨论】:

          【解决方案7】:

          首先检查可以发布解决方案(项目)的开发人员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;包 /p:Configuration=DEBUG /p:OutputPath="obj\DEBUG" /p:DeployIisAppPath="Default Web Site/jenkinsdemoapp" /p:VisualStudioVersion=12.0

          【讨论】:

          • 抱歉 shammakalubo 你对这个问题的理解有很大的误解。
          • @shammakalubo 答案是正确的,但只是没有完全说明。需要将此参数添加到OP提到的命令中,然后将变为:MSBuild C:\PathToMyProject\MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0此参数是我缺少的并修复了我的问题。你只需要完整地提到答案!
          • @WaqasShah 谢谢,正如你提到的,我已经编辑了我的答案并发布了完整的代码。
          【解决方案8】:

          从项目文件夹运行

          msbuild /p:DeployOnBuild=true /p:PublishProfile="release-file.pubxml" /p:AspnetMergePath="C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin \NETFX 4.8 工具" /p:Configuration=Release

          这会处理 web.config Transform 和 AspnetMergePath

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-08-29
            • 1970-01-01
            • 1970-01-01
            • 2020-12-11
            • 1970-01-01
            • 2022-07-08
            • 1970-01-01
            相关资源
            最近更新 更多