【问题标题】:Automatically increment "minimum required version" in a ClickOnce deployment?在 ClickOnce 部署中自动增加“最低要求的版本”?
【发布时间】:2008-10-14 19:25:02
【问题描述】:

有没有办法自动增加 ClickOnce 部署中的“最低要求版本”字段以始终等于当前内部版本号?基本上,我总是希望我的部署在启动时自动更新。

我怀疑我需要一些构建前/构建后的事件,但我希望有更简单的方法。

【问题讨论】:

  • 我有一个干净的解决方案。请看我的回答here

标签: msbuild clickonce


【解决方案1】:

我回答这个问题可能有点晚了,但我发现在谷歌上很难找到解决方案,但最终想通了,所以想分享一下。

对于 MSBuild 版本 4(VS2010 和 VS2012),这可以通过插入以下目标来实现:

  <Target Name="AutoSetMinimumRequiredVersion" BeforeTargets="GenerateDeploymentManifest">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output PropertyName="MinimumRequiredVersion" TaskParameter="OutputVersion"  />
    </FormatVersion>
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
      <Output PropertyName="_DeploymentBuiltMinimumRequiredVersion" TaskParameter="OutputVersion"  />
    </FormatVersion>
  </Target>

$(ApplicationVersion) 与您可以在 VS IDE 的项目发布窗口中手动设置的设置相同,修订部分设置为星号。 $(ApplicationRevision) 是用于已发布版本的实际修订。 FormatVersion 任务是一个内置的 MSBuild 任务,它将两者格式化为一个完整的版本号。

这会将“最低要求版本”设置为与“发布版本”相同,从而确保用户始终安装新部署,即没有跳过更新的选项。

当然,如果你不想将最低要求的版本设置为发布版本,而想使用不同的源属性,那么直接修改目标就可以了,但原理是一样的。

【讨论】:

  • 我花了一段时间才弄清楚该放在哪里。您必须卸载项目,右键单击并选择“编辑 Test.csproj”(或在编辑器中在 VS 外部打开它)。
  • “MinimumRequiredVersion”和“_DeploymentBuiltMinimumRequiredVersion”有什么区别?如果我删除第一个 FormatVersion 部分,它似乎仍然有效。什么时候需要?
  • 请注意,虽然这将正确部署 MinimumRequiredVersion 的值,但该值不会出现在您的项目文件或发布 UI 中。
  • 谢谢你,这太棒了,应该是公认的答案
【解决方案2】:

我最终实际上将一个 AddIn 滚动到 VS,它可以同步所有版本号,然后只需单击一下即可构建和发布。这很容易。

    Public Sub Publish()
        Try
            Dim startProjName As String = Nothing
            Dim targetProj As Project = Nothing
            Dim soln As Solution2 = TryCast(Me._applicationObject.DTE.Solution, Solution2)
            If soln IsNot Nothing Then
                For Each prop As [Property] In soln.Properties
                    If prop.Name = "StartupProject" Then
                        startProjName = prop.Value.ToString()
                        Exit For
                    End If
                Next
                If startProjName IsNot Nothing Then
                    For Each proj As Project In soln.Projects
                        If proj.Name = startProjName Then
                            targetProj = proj
                            Exit For
                        End If
                    Next
                    If targetProj IsNot Nothing Then
                        Dim currAssemVersionString As String = targetProj.Properties.Item("AssemblyVersion").Value.ToString
                        Dim currAssemVer As New Version(currAssemVersionString)
                        Dim newAssemVer As New Version(currAssemVer.Major, currAssemVer.Minor, currAssemVer.Build, currAssemVer.Revision + 1)
                        targetProj.Properties.Item("AssemblyVersion").Value = newAssemVer.ToString()
                        targetProj.Properties.Item("AssemblyFileVersion").Value = newAssemVer.ToString()
                        Dim publishProps As Properties = TryCast(targetProj.Properties.Item("Publish").Value, Properties)
                        Dim shouldPublish As Boolean = False
                        If publishProps IsNot Nothing Then
                            shouldPublish = CBool(publishProps.Item("Install").Value)
                            If shouldPublish Then
                                targetProj.Properties.Item("GenerateManifests").Value = "true"
                                publishProps.Item("ApplicationVersion").Value = newAssemVer.ToString()
                                publishProps.Item("MinimumRequiredVersion").Value = newAssemVer.ToString()
                                publishProps.Item("ApplicationRevision").Value = newAssemVer.Revision.ToString()
                            End If
                        End If
                        targetProj.Save()
                        Dim build As SolutionBuild2 = TryCast(soln.SolutionBuild, SolutionBuild2)
                        If build IsNot Nothing Then
                            build.Clean(True)
                            build.Build(True)
                            If shouldPublish Then
                                If build.LastBuildInfo = 0 Then

                                    build.Publish(True)
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

【讨论】:

  • @Bob 有趣的是,您的解决方案适用于非 VSTO 项目,但“发布”属性对于 VSTO 项目无效。
  • 您可以使用 VSTO 项目中“发布”选项卡上的按钮进行发布吗?
  • 是的,发布按钮工作正常。你试过了吗?有可能是环境问题,但我认为这对于 VSTO 项目来说简直是坏事。
  • VS AddIn 在项目中有很多开发人员的情况下并不是最好的方法。您是否找到了使用 Build 事件的方法?
【解决方案3】:

开箱即用,我不相信有办法。不过,自己旋转并不费力。

我使用的方法如下:

1) 创建一个 Version.Properties 文件

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Util-VersionMajor>1</Util-VersionMajor>
    <Util-VersionMinor>11</Util-VersionMinor>
    <Util-VersionBuild>25</Util-VersionBuild>
    <Util-VersionRevision>0</Util-VersionRevision>
    <Util-VersionDots>$(Util-VersionMajor).$(Util-VersionMinor).$(Util-VersionBuild).$(Util-VersionRevision)</Util-VersionDots>
    <Util-VersionUnders>$(Util-VersionMajor)_$(Util-VersionMinor)_$(Util-VersionBuild)_$(Util-VersionRevision)</Util-VersionUnders>
    <MinimumRequiredVersion>$(Util-VersionDots)</MinimumRequiredVersion>
    <ApplicationVersion>$(Util-VersionDots)</ApplicationVersion>
    <ApplicationRevision>$(Util-VersionRevision)</ApplicationRevision>
  </PropertyGroup>
</Project>

2) 将 Version.Properties 文件导入到您的项目文件中

3) 创建一个任务以在 Build 上增加版本。这是我的

<Target Name="IncrementVersion" DependsOnTargets="Build" Condition="'$(BuildingInsideVisualStudio)'==''">
    <ItemGroup>
      <Util-VersionProjectFileItem Include="$(Util-VersionProjectFile)" />
    </ItemGroup>
    <PropertyGroup>
      <Util-VersionProjectFileFullPath>@(Util-VersionProjectFileItem->'%(FullPath)')</Util-VersionProjectFileFullPath>
    </PropertyGroup>
    <Exec Command="&quot;$(TfCommand)&quot; get /overwrite /force /noprompt &quot;$(Util-VersionProjectFileFullPath)&quot;" Outputs="" />
    <Exec Command="&quot;$(TfCommand)&quot; checkout /lock:checkout &quot;$(Util-VersionProjectFileFullPath)&quot;" Outputs="" />
    <Version Major="$(Util-VersionMajor)" Minor="$(Util-VersionMinor)" Build="$(Util-VersionBuild)" Revision="$(Util-VersionRevision)" RevisionType="None" BuildType="Increment">
      <Output TaskParameter="Major" PropertyName="Util-VersionMajor" />
      <Output TaskParameter="Minor" PropertyName="Util-VersionMinor" />
      <Output TaskParameter="Build" PropertyName="Util-VersionBuild" />
      <Output TaskParameter="Revision" PropertyName="Util-VersionRevision" />
    </Version>
    <XmlUpdate Prefix="msb" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XPath="/msb:Project/msb:PropertyGroup/msb:Util-VersionMajor" XmlFileName="$(Util-VersionProjectFile)" Value="$(Util-VersionMajor)" />
    <XmlUpdate Prefix="msb" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XPath="/msb:Project/msb:PropertyGroup/msb:Util-VersionMinor" XmlFileName="$(Util-VersionProjectFile)" Value="$(Util-VersionMinor)" />
    <XmlUpdate Prefix="msb" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XPath="/msb:Project/msb:PropertyGroup/msb:Util-VersionBuild" XmlFileName="$(Util-VersionProjectFile)" Value="$(Util-VersionBuild)" />
    <XmlUpdate Prefix="msb" Namespace="http://schemas.microsoft.com/developer/msbuild/2003" XPath="/msb:Project/msb:PropertyGroup/msb:Util-VersionRevision" XmlFileName="$(Util-VersionProjectFile)" Value="$(Util-VersionRevision)" />
    <Exec Command="&quot;$(TfCommand)&quot; checkin /override:AutoBuildIncrement /comment:***NO_CI***  &quot;$(Util-VersionProjectFileFullPath)&quot;" />
    <Exec Command="&quot;$(TfCommand)&quot; get /overwrite /force /noprompt &quot;$(Util-AssemblyInfoFile)&quot;" Outputs="" />
    <Exec Command="&quot;$(TfCommand)&quot; checkout /lock:checkout &quot;$(Util-AssemblyInfoFile)&quot;" Outputs="" />
    <AssemblyInfo CodeLanguage="CS" OutputFile="$(Util-AssemblyInfoFile)" AssemblyConfiguration="$(Configuration)" AssemblyVersion="$(Util-VersionMajor).$(Util-VersionMinor).$(Util-VersionBuild).$(Util-VersionRevision)" AssemblyFileVersion="$(Util-VersionMajor).$(Util-VersionMinor).$(Util-VersionBuild).$(Util-VersionRevision)" />
    <Exec Command="&quot;$(TfCommand)&quot; checkin /override:AutoBuildIncrement /comment:***NO_CI***  &quot;$(Util-AssemblyInfoFile)&quot;" />
  </Target>

这里有一些额外的点击技巧http://weblogs.asp.net/sweinstein/archive/2008/08/24/top-5-secrets-of-net-desktop-deployment-wizards.aspx

【讨论】:

    【解决方案4】:

    我是这样处理这个的。首先,我创建了一个包含字符串替换的自定义任务:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Build.Utilities;
    using Microsoft.Build.Framework;
    
    namespace SynchBuild
    {
        public class RemoveAsterisk : Task
        {
            private string myVersion;
    
            [Required]
            public string Version
            {
                set{myVersion = value;}
            }
    
    
            [Output]
            public string ReturnValue
            {
                get { return myVersion.Replace("*", ""); }
            }
    
    
            public override bool Execute()
            {
                return true;
            }
        }
    }
    

    所以它被内置到 SynchBuild.dll 中,您可以在下面的 UsingTask 中看到它。现在我尝试只覆盖 MinimumRequiredVersion 属性,但它似乎没有被拾取,所以我只是通过在我的 csproj 文件末尾添加以下行来覆盖 GenerateApplicationManifest 目标:

    <UsingTask AssemblyFile="$(MSBuildExtensionsPath)\WegmansBuildTasks\SynchBuild.dll" TaskName="SynchBuild.RemoveAsterisk" />
      <Target Name="GenerateDeploymentManifest" DependsOnTargets="GenerateApplicationManifest" Inputs="&#xD;&#xA;            $(MSBuildAllProjects);&#xD;&#xA;            @(ApplicationManifest)&#xD;&#xA;            " Outputs="@(DeployManifest)">
        <RemoveAsterisk Version="$(ApplicationVersion)$(ApplicationRevision)">
          <Output TaskParameter="ReturnValue" PropertyName="MinimumRequiredVersion" />
        </RemoveAsterisk>
        <GenerateDeploymentManifest MinimumRequiredVersion="$(MinimumRequiredVersion)" AssemblyName="$(_DeploymentDeployManifestIdentity)" AssemblyVersion="$(_DeploymentManifestVersion)" CreateDesktopShortcut="$(CreateDesktopShortcut)" DeploymentUrl="$(_DeploymentFormattedDeploymentUrl)" Description="$(Description)" DisallowUrlActivation="$(DisallowUrlActivation)" EntryPoint="@(_DeploymentResolvedDeploymentManifestEntryPoint)" ErrorReportUrl="$(_DeploymentFormattedErrorReportUrl)" Install="$(Install)" MapFileExtensions="$(MapFileExtensions)" MaxTargetPath="$(MaxTargetPath)" OutputManifest="@(DeployManifest)" Platform="$(PlatformTarget)" Product="$(ProductName)" Publisher="$(PublisherName)" SuiteName="$(SuiteName)" SupportUrl="$(_DeploymentFormattedSupportUrl)" TargetCulture="$(TargetCulture)" TargetFrameworkVersion="$(TargetFrameworkVersion)" TrustUrlParameters="$(TrustUrlParameters)" UpdateEnabled="$(UpdateEnabled)" UpdateInterval="$(_DeploymentBuiltUpdateInterval)" UpdateMode="$(UpdateMode)" UpdateUnit="$(_DeploymentBuiltUpdateIntervalUnits)" Condition="'$(GenerateClickOnceManifests)'=='true'">
          <Output TaskParameter="OutputManifest" ItemName="FileWrites" />
    </GenerateDeploymentManifest>
      </Target>
    

    最终结果是我们获取应用版本和修订版,将它们组合起来,去掉星号,然后设置最低要求的版本。我在我的发布属性集中设置了自动递增应用程序版本,这就是递增发生的方式,然后我只是将 minimumrequiredversion 设置为始终匹配。我不使用团队构建,这只是为了让使用 Visual Studio 的开发人员可以进行所有需要的 clickonce 部署。希望这会有所帮助。

    【讨论】:

      【解决方案5】:

      如果您是从 Visual Studio 发布 ClickOnce 应用程序,那么只需在您的项目中安装 AutoUpdateProjectsMinimumRequiredClickOnceVersion NuGet Package 即可。

      如果您从构建服务器或其他脚本发布,则可以使用Set-ProjectFilesClickOnceVersion PowerShell script。我的博客更详细地描述了how to setup your build server to accommodate publishing ClickOnce applications

      【讨论】:

        【解决方案6】:

        您在寻找应用程序更新吗?

        在解决方案资源管理器中右键单击项目,然后单击发布... 是获取应用程序更新的错误方法。您必须右键单击您的项目并单击“属性”,然后单击“发布”选项卡。单击更新...按钮,然后选中“应用程序应检查更新”复选框。您还可以在此处指定应用程序所需的最低版本。(我没有使用过该功能,但更新功能是我使用 ClickOnce 的核心原因,而且效果很好。)

        【讨论】:

        • 我想做的是自动增加“应用程序所需的最低版本”以匹配即将发布的当前版本。
        • 我明白了。这听起来很有用。事实上,如果 MS 很聪明,他们就会把它做成一个内置的复选框功能...... :-)
        • 问题是如何自动增加该功能。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-28
        相关资源
        最近更新 更多