Автоматически увеличивать "минимальную требуемую версию" при развертывании ClickOnce?
Есть ли способ автоматически увеличивать поля "минимальная требуемая версия" при развертывании ClickOnce, чтобы всегда соответствовать текущему номеру сборки? В принципе, я всегда хочу, чтобы мое развертывание автоматически обновлялось при запуске.
Я подозреваю, что мне понадобятся некоторые предварительные или пост-сборные события, но я надеюсь, что там будет проще.
Ответы
Ответ 1
Возможно, я немного опоздал с ответом на этот вопрос, но мне было сложно найти решение на google, но в итоге разобралось, так что подумал, что буду делиться.
С 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, которая форматирует два в один полный номер версии.
Это установит "Минимальная требуемая версия" таким же, как "Версия публикации", поэтому гарантирует, что новое развертывание всегда будет установлено пользователями, то есть нет опции "Пропустить обновление".
Конечно, если вы не хотите устанавливать минимальную требуемую версию для публикации и хотите использовать другое исходное свойство, то прямо изменить цель, но принцип тот же.
Ответ 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
Ответ 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=""$(TfCommand)" get /overwrite /force /noprompt "$(Util-VersionProjectFileFullPath)"" Outputs="" />
<Exec Command=""$(TfCommand)" checkout /lock:checkout "$(Util-VersionProjectFileFullPath)"" 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=""$(TfCommand)" checkin /override:AutoBuildIncrement /comment:***NO_CI*** "$(Util-VersionProjectFileFullPath)"" />
<Exec Command=""$(TfCommand)" get /overwrite /force /noprompt "$(Util-AssemblyInfoFile)"" Outputs="" />
<Exec Command=""$(TfCommand)" checkout /lock:checkout "$(Util-AssemblyInfoFile)"" 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=""$(TfCommand)" checkin /override:AutoBuildIncrement /comment:***NO_CI*** "$(Util-AssemblyInfoFile)"" />
</Target>
Некоторые дополнительные трюки clickonce здесь 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, который вы видите в разделе UseTask ниже. Теперь я попробовал просто перезаписать свойство MinimumRequiredVersion, но он, похоже, не получил, поэтому я просто перезаписал цель GenerateApplicationManifest, добавив следующие строки в конец моего файла csproj:
<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\WegmansBuildTasks\SynchBuild.dll" TaskName="SynchBuild.RemoveAsterisk" />
<Target Name="GenerateDeploymentManifest" DependsOnTargets="GenerateApplicationManifest" Inputs="
 $(MSBuildAllProjects);
 @(ApplicationManifest)
 " 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>
В результате мы получаем версию приложения и версию, объединяем их, удаляем звездочку, а затем устанавливаем минимально требуемую версию. У меня есть версия приложения с добавлением автоматического увеличения в моих настройках публикации, чтобы так, как происходит увеличение, тогда я просто устанавливаю минимальное requiredversion, чтобы всегда соответствовать. Я не использую сборку команд, это просто спроектировано так, чтобы разработчик использовал визуальную студию может сделать все развертывания clickonce. Надеюсь, это поможет.
Ответ 5
Если вы публикуете приложение ClickOnce из Visual Studio, просто установите AutoUpdateProjectsMinimumRequiredClickOnceVersion NuGet Package в свой проект, и вам хорошо идти.
Если вы публикуете с сервера сборки или другого script, вы можете использовать Set-ProjectFilesClickOnceVersion PowerShell script. В моем блоге более подробно описывается как настроить сервер сборки для размещения публикаций приложений ClickOnce.
Ответ 6
Вы ищете обновления приложений?
Щелчок правой кнопкой мыши по проекту в обозревателе решений и последующее нажатие кнопки "Опубликовать..." - это неправильный способ получения обновлений приложений. Вы должны щелкнуть правой кнопкой мыши свой проект и щелкнуть "Свойства", а затем перейти на вкладку "Опубликовать". Нажмите кнопку "Обновления...", а затем установите флажок "Приложение должно проверить наличие обновлений". Там вы также можете указать минимальную требуемую версию для приложения. (Я не использовал эту функциональность, но функциональность Updates является основной причиной, по которой я использую ClickOnce, и она отлично работает.)