Incrementa automaticamente & # 8220; versione minima richiesta & # 8221; in una distribuzione ClickOnce?
Domanda
Esiste un modo per incrementare automaticamente la "versione minima richiesta" campi in una distribuzione ClickOnce per uguagliare sempre il numero di build corrente? Fondamentalmente, voglio sempre che la mia distribuzione venga automaticamente aggiornata all'avvio.
Sospetto che avrò bisogno di alcuni eventi pre / post build, ma spero che ci sia un modo più semplice.
Soluzione
Potrei essere un po 'in ritardo con la risposta a questa, ma ho trovato difficile trovare la soluzione su Google, ma alla fine l'ho capito, quindi ho pensato di condividere.
Con MSBuild versione 4 (VS2010 e VS2012) questo può essere ottenuto inserendo il seguente target:
<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) è la stessa impostazione che è possibile impostare manualmente nella finestra Pubblica del progetto nell'IDE VS, con la parte di revisione impostata su un asterisco. $ (ApplicationRevision) è la revisione effettiva utilizzata per la versione pubblicata. L'attività FormatVersion è un'attività integrata di MSBuild che formatta i due in un unico numero di versione completo.
Questo imposterà la 'Versione minima richiesta' in modo che sia la stessa della 'Versione di pubblicazione' assicurando quindi che la nuova distribuzione sarà sempre installata dagli utenti, cioè nessuna opzione per saltare l'aggiornamento.
Naturalmente, se non si desidera impostare la versione minima richiesta sulla versione di pubblicazione e si desidera utilizzare una proprietà di origine diversa, è semplice modificare la destinazione, ma il principio è lo stesso.
Altri suggerimenti
Ho finito per inviare effettivamente un AddIn a VS che sincronizza tutti i numeri di versione, quindi crea e pubblica con un solo clic. È stato abbastanza facile.
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
Fuori dagli schemi, non credo che ci sia un modo. Tuttavia, non è uno sforzo eccessivo far girare il tuo.
L'approccio che utilizzo è il seguente:
1) crea un file 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) Importa il file Version.Properties nei tuoi file di progetto
3) Crea un'attività per incrementare la versione su Build. Ecco il mio
<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>
Alcuni trucchi aggiuntivi per clickonce qui http://weblogs.asp.net/sweinstein/archive/2008/08/24/top-5-secrets-of-net-desktop-deployment-wizards.aspx
Ecco come ho gestito questo. Innanzitutto ho creato un'attività personalizzata che avvolge la sostituzione della stringa:
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;
}
}
}
In modo che venga integrato in SynchBuild.dll che vedi indicato nel UsingTask di seguito. Ora ho provato a sovrascrivere la proprietà MinimumRequiredVersion, ma non sembrava essere stata presa, quindi ho semplicemente sovrascritto il target GenerateApplicationManifest aggiungendo le seguenti righe alla fine del mio file 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>
Il risultato finale è prendere la versione dell'app e la revisione, combinarli, rimuovere l'asterisco, quindi impostare la versione minima richiesta. Ho impostato la versione dell'app di incremento automatico nelle mie proprietà di pubblicazione in modo che avvenga l'incremento, quindi sto solo impostando la versione minima richiesta affinché corrisponda sempre. Non utilizzo il team building, questo è progettato in modo tale che uno sviluppatore che utilizza Visual Studio può effettuare tutte le distribuzioni clickonce richieste. Spero che questo aiuti.
Se stai pubblicando la tua applicazione ClickOnce da Visual Studio, installa AutoUpdateProjectsMinimumRequiredClickOn nel tuo progetto e sei a posto.
Se pubblichi da un server di build o da altri script, puoi utilizzare Set-ProjectFilesClickOnceVersion PowerShell sceneggiatura . Il mio blog descrive in modo più dettagliato come configurare il tuo server di build per ospitare la pubblicazione di applicazioni ClickOnce .
Cerchi aggiornamenti dell'applicazione?
Fare clic destro sul progetto in Esplora soluzioni e quindi fare clic su Pubblica ... è il modo sbagliato di ottenere gli aggiornamenti dell'applicazione. Devi fare clic con il pulsante destro del mouse sul progetto e fare clic su Proprietà, quindi fare clic sulla scheda Pubblica. Fai clic sul pulsante Aggiornamenti ... e quindi seleziona " L'applicazione dovrebbe verificare la presenza di aggiornamenti " casella di controllo. Lì puoi anche specificare una versione minima richiesta per l'applicazione. (Non ho usato quella funzionalità ma la funzionalità Aggiornamenti è il motivo principale per cui utilizzo ClickOnce e funziona alla grande.)