如何通过 CruiseControl.NET 发布 ClickOnce 应用程序?

Posted

技术标签:

【中文标题】如何通过 CruiseControl.NET 发布 ClickOnce 应用程序?【英文标题】:How can you publish a ClickOnce application through CruiseControl.NET? 【发布时间】:2008-08-15 17:08:19 【问题描述】:

我的开发服务器上安装了 CruiseControl.NET 1.4 版。每当开发人员签入代码时,都会进行编译。

现在我们可以开始将应用程序提供给测试人员了。我们想使用 ClickOnce 来分发应用程序,其想法是当测试人员去测试应用程序时,他们拥有最新的构建。

我找不到使用 CruiseControl.NET 实现这一点的方法。我们正在使用 MSBUILD 来执行构建。

【问题讨论】:

【参考方案1】:

我们已经做到了,可以给你一些开始的指导。

你应该注意的两件事:

MSBuild 可以为您生成必要的部署文件。 MSBuild 不会将文件部署到 FTP 或 UNC 共享。为此,您需要一个单独的步骤。

要使用 MSBuild 生成 ClickOnce 清单,您需要发出以下命令:

msbuild /target:publish /p:Configuration=Release /p:Platform=AnyCPU; "c:\yourProject.csproj"

这将告诉 MSBuild 构建您的项目并在 bin\Release\YourProject.publish 目录中生成 ClickOnce 部署文件。

剩下的就是将这些文件复制到 FTP/UNC 共享/任何位置,一切就绪。

您可以告诉 CruiseControl.NET 使用这些 MSBuild 参数进行构建。

然后,您将需要 CruiseControl.NET 构建任务来获取生成的部署文件并将它们复制到 FTP 或 UNC 共享。我们为此使用了一个自定义的小型 C# 控制台程序,但您也可以轻松地使用 Powershell 脚本。

【讨论】:

我只想指出这有点过时了。假设您的帖子是正确的,MSBuild 已更新以支持部署到 UNC 共享,我现在在许多活动项目中都这样做。 谢谢,詹姆斯。是的,这个问题最初是在 2008 年回答的,当时这一切都是新鲜而性感的; 7 年后可能不再相关。【参考方案2】:

感谢所有帮助。我们实施的最终解决方案从每个答案中提取了一些内容。

我们发现使用简单的批处理文件可以更轻松地处理多个环境。我并不是说这是最好的方法,但是对于我们给定的场景和要求,这很有效。用您的项目名称补充“项目”,用您的环境名称(开发、测试、阶段、生产等)补充“环境”。

这是我们“ccnet.config”文件的任务区。

<!-- override settings  -->
<exec>
    <executable>F:\Source\Project\Environment\CruiseControl\CopySettings.bat</executable>
</exec>

<!-- compile -->
<msbuild>
    <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
    <workingDirectory>F:\Source\Project\Environment\</workingDirectory>
    <projectFile>Project.sln</projectFile>
    <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
    <targets>Rebuild</targets>
    <timeout>0</timeout>
    <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>

<!-- clickonce publish  -->
<exec>
    <executable>F:\Source\Project\Environment\CruiseControl\Publish.bat</executable>
</exec>

您会注意到的第一件事是 CopySettings.bat 运行。这会复制环境的特定设置,例如数据库连接。

接下来,标准的 MSBUILD 任务运行。任何编译错误都会在这里捕获并正常处理。

最后要执行的是 Publish.bat。这实际上从命令行再次执行 MSBUILD “重建”,并且来自 CruiseControl 的参数会自动传入和构建。接下来,为“发布”目标调用 MSBUILD。发布重建时为发布提供完全相同的参数。这使内部版本号保持同步。此外,我们的可执行文件命名不同(即 - ProjectDev 和 ProjectTest)。我们最终会得到不同的版本号和名称,这允许 ClickOnce 完成它的工作。

Publish.bat 的最后一部分将实际文件复制到它们的新位置。我们不使用 publish.htm,因为我们所有的用户都在网络上,我们只是给他们桌面上清单文件的快捷方式,他们可以单击并始终运行正确的可执行文件,其版本号与巡航控制。

这里是 CopySettings.bat

XCOPY "F:\Source\Project\Environment\CruiseControl\Project\app.config" "F:\Source\Project\Environment\Project" /Y /I /R
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.Designer.vb" "F:\Source\Project\Environment\Project\My Project" /Y /I /R
XCOPY "F:\Source\Project\Environment\CruiseControl\Project\My Project\Settings.settings" "F:\Source\Project\Environment\Project\My Project" /Y /I /R

最后,这里是 Publish.bat

C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:rebuild "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationRevision=%CCNetLabel% /property:AssemblyName="ProjectEnvironment" /property:PublishUrl="\\Server\bin\Project\Environment\\"
C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /target:publish "F:\Source\Project\Environment\Project\Project.vbproj" /property:ApplicationVersion="1.0.0.%CCNetLabel%" /property:AssemblyVersion="1.0.0.%CCNetLabel%" /property:AssemblyName="ProjectEnvironment" 

XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish" "F:\Binary\Project\Environment" /Y /I
XCOPY "F:\Source\Project\Environment\Project\bin\Debug\app.publish\Application Files" "F:\Binary\Project\Environment\Application Files" /Y /I /S

就像我说的那样,它可能没有按照 CruiseControl 和 MSBUILD 开发人员的预期工作方式完成,但它确实有效。如果您需要在昨天完成这项工作,它可能就是您正在寻找的解决方案。祝你好运!

【讨论】:

【参考方案3】:

我记得去年我正在为一个 ClickOnce 项目做这件事。我记得我花了很长时间才弄清楚,但它就在这里。我希望我的脚本做的是生成一个指向我们的开发环境的不同安装程序和一个用于生产环境的不同安装程序。不仅如此,我还需要它来注入正确的版本信息,这样现有的客户就会“意识到”有一个新版本,这就是 clickOnce 的全部意义所在。 在此脚本中,您必须替换为您自己的服务器名称等。诀窍是保存 publish.htm 和 project.publish 文件,并根据 CC.NET 提供给您的版本注入新的版本号。

这是我的构建脚本的样子:

<target name="deployProd">
  <exec program="<framework_dir>\msbuild.exe" commandline="<project>/<project>.csproj /property:Configuration=PublishProd /property:ApplicationVersion=$build.label.*;PublishUrl=\\<prod_location>\binups$\;InstallUrl=\\<prod_location>\binups$\;UpdateUrl=\\<prod_location>\binups$\;BootstrapperComponentsUrl=\\<prod_location>\prereqs$\ /target:publish"/>

  <copy todir="<project>\bin\PublishProd\<project>.publish">

    <fileset basedir=".">
      <include name="publish.htm"/>
    </fileset>

    <filterchain>
      <replacetokens>
        <token key="CURRENT_VERSION" value="$build.label"/>
      </replacetokens>
     </filterchain>
  </copy>

</target>

希望对你有帮助

【讨论】:

【参考方案4】:

只要能够在 CCNET.config msbuild 任务中传递 $CCNetLabel 将是一个很大的改进。

【讨论】:

【参考方案5】:

您想在 msbuild 中使用 ClickOnce 清单生成任务。这个过程有点冗长,所以我只想为您指出几个链接。这是reference on msdn 和sample article,希望能帮助您入门。

【讨论】:

以上是关于如何通过 CruiseControl.NET 发布 ClickOnce 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

CruiseControl.Net 在使用 msbuild 任务的项目后重新启动

FXcop 和 Msbuild 与 CruiseControl.NET

使用 CruiseControl.NET 和 MSBuild 发布网站

CruiseControl.Net Build Publisher - 只发布编译文件

CruiseControl [.Net] 与 TeamCity 的持续集成?

MSTest & CruiseControl.Net