Skip to content

Commit ae4421a

Browse files
committed
- Fixed quite a few bugs in the script: parameter sets not working quite right, not using the Revision part when provided, lots of PowerShell syntax/null ref errors.
- Minor refactorings. - Got unit test working properly, but still need to add more.
1 parent ea2e0ed commit ae4421a

2 files changed

Lines changed: 49 additions & 30 deletions

File tree

Set-ProjectFilesClickOnceVersion.ps1

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
Author: Daniel Schroeder
6060
Version: 2.0.0
6161
#>
62-
62+
[CmdletBinding(DefaultParameterSetName="UseBuildSystemsBuildId")]
6363
Param
6464
(
6565
[Parameter(Mandatory=$true,HelpMessage="The project file to update the ClickOnce Version in.")]
@@ -192,12 +192,20 @@ function Set-XmlNodesElementTextValue([xml]$xml, $node, $elementName, $textValue
192192
# Define the max value that a version part is allowed to have (16-bit int).
193193
[int]$maxVersionPartValueAllowed = 65535
194194

195-
# The regex used to obtain the Major.Minor.Build parts from a version number.
196-
$majorMinorBuildRegex = New-Object System.Text.RegularExpressions.Regex "(?<MajorMinor>^\d+\.\d+)\.(?<Build>\d+)", SingleLine
195+
# The regex used to obtain the Major.Minor.Build.Revision parts from a version number (revision is optional).
196+
$versionNumberRegex = New-Object System.Text.RegularExpressions.Regex "(?<MajorMinor>^\d+\.\d+)\.(?<Build>\d+)(\.(?<Revision>\d+))?", SingleLine
197197

198198
# Open the Xml file and get the <PropertyGroup> elements with the ClickOnce properties in it.
199199
[xml]$xml = Get-Content -Path $ProjectFilePath
200-
$clickOncePropertyGroups = Get-XmlNodes -XmlDocument $xml -NodePath 'Project.PropertyGroup' | Where-Object { $_.ApplicationVersion -ne $null }
200+
$propertyGroups = Get-XmlNodes -XmlDocument $xml -NodePath 'Project.PropertyGroup'
201+
[Array]$clickOncePropertyGroups = $propertyGroups | Where-Object {
202+
try
203+
{
204+
$_.ApplicationVersion -ne $null
205+
return $true
206+
}
207+
catch { return $false }
208+
}
201209

202210
# If no ClickOnce deployment settings were found throw an error.
203211
if ($clickOncePropertyGroups -eq $null -or $clickOncePropertyGroups.Count -eq 0)
@@ -206,75 +214,82 @@ if ($clickOncePropertyGroups -eq $null -or $clickOncePropertyGroups.Count -eq 0)
206214
}
207215

208216
# Iterate over each <PropertyGroup> that has ClickOnce deployment settings and update them.
209-
foreach ($propertyGroup in $clickOncePropertyGroups)
217+
foreach ($clickOncePropertyGroup in $clickOncePropertyGroups)
210218
{
211219
# If the Version to use was not provided, get it from the project file.
212220
$appVersion = $Version
213221
if ([string]::IsNullOrEmpty($appVersion))
214222
{
215-
$appVersion = $propertyGroup.ApplicationVersion
223+
$appVersion = $clickOncePropertyGroup.ApplicationVersion
216224
}
217225

218226
# Get the Major, Minor, and Build parts of the version number.
219-
$majorMinorBuildMatch = $majorMinorBuildRegex.Match($appVersion)
227+
$majorMinorBuildMatch = $versionNumberRegex.Match($appVersion)
220228
if (!$majorMinorBuildMatch.Success)
221229
{
222230
throw "The version number '$appVersion' does not seem to have valid Major.Minor.Build version parts."
223231
}
224232
$majorMinor = $majorMinorBuildMatch.Groups["MajorMinor"].Value
225233
$build = $majorMinorBuildMatch.Groups["Build"].Value
234+
$revision = -1
235+
236+
# If a Revision was specified in the Version, get it.
237+
if (![string]::IsNullOrWhiteSpace($majorMinorBuildMatch.Groups["Revision"]))
238+
{
239+
$revision = $majorMinorBuildMatch.Groups["Revision"]
240+
}
226241

227242
# If we should be using the BuildSystemsBuildId for the Build and Revision.
228243
if ($BuildSystemsBuildId -gt -1)
229244
{
230245
# Use a calculation for the Build and Revision to prevent the Revision value from being too large, and to increment the Build value as the BuildSystemsBuildId continues to grow larger.
231246
$build = $BuildSystemsBuildId / $maxVersionPartValueAllowed
232-
$Revision %= $maxVersionPartValueAllowed
247+
$revision = $BuildSystemsBuildId % $maxVersionPartValueAllowed
233248
}
234249

235-
# Else if we should be incrementing the file's revision, get the Revision from the project file.
236-
if ($IncrementProjectFilesRevision)
250+
# Else if we should be incrementing the file's revision, or we don't have the revision yet, get the Revision from the project file.
251+
if ($IncrementProjectFilesRevision -or $revision -eq -1)
237252
{
238253
# If the Revision is missing from the file, or not in a valid format, throw an error.
239-
if ($propertyGroup.ApplicationRevision -eq $null)
254+
$applicationRevisionString = $clickOncePropertyGroup.ApplicationRevision
255+
if ($applicationRevisionString -eq $null)
240256
{
241257
throw "Could not find the <ApplicationRevision> element in the project file '$ProjectFilePath'."
242-
}
243-
$applicationRevisionString = $propertyGroup.ApplicationRevision
244-
if (!($applicationRevisionString -imatch '^\d+$').Success)
258+
}
259+
if (!($applicationRevisionString -imatch '^\d+$'))
245260
{
246261
throw "The <ApplicationRevision> elements value '$applicationRevisionString' in the file '$ProjectFilePath' does not appear to be a valid integer."
247262
}
248263

249-
$Revision = [int]::Parse($applicationRevisionString)
264+
$revision = [int]::Parse($applicationRevisionString)
250265

251266
# If the Revision should be incremented, do it.
252267
if ($IncrementProjectFilesRevision)
253268
{
254-
$Revision = $Revision + 1
269+
$revision = $revision + 1
255270

256271
# Make sure the Revision version part is not greater than the max allowed value.
257-
if ($Revision -gt $maxVersionPartValueAllowed)
272+
if ($revision -gt $maxVersionPartValueAllowed)
258273
{
259-
Write-Warning "The Revision value '$Revision' to use for the last part of the version number is greater than the max allowed value of '$maxVersionPartValueAllowed'. The modulus will be used for the revision instead. If this results in your ClickOnce deployment not downloading the latest update and giving an error message like 'Cannot activate a deployment with earlier version than the current minimum required version of the application.' then you will need to increment the Build part of the ClickOnce <ApplicationVersion> value stored in the project file."
260-
$Revision %= $maxVersionPartValueAllowed
274+
Write-Warning "The Revision value '$revision' to use for the last part of the version number is greater than the max allowed value of '$maxVersionPartValueAllowed'. The modulus will be used for the revision instead. If this results in your ClickOnce deployment not downloading the latest update and giving an error message like 'Cannot activate a deployment with earlier version than the current minimum required version of the application.' then you will need to increment the Build part of the ClickOnce <ApplicationVersion> value stored in the project file."
275+
$revision %= $maxVersionPartValueAllowed
261276
}
262277
}
263278
}
264279

265280
# Create the version number to use for the ClickOnce version.
266281
$newMajorMinorBuild = "$majorMinor.$build"
267-
$newVersionNumber = "$newMajorMinorBuild.$Revision"
282+
$newVersionNumber = "$newMajorMinorBuild.$revision"
268283
Write-Output "Updating version number to be '$newVersionNumber'."
269284

270285
# Write the new values to the file.
271-
Set-XmlNodesElementTextValue -xml $xml -node $propertyGroup -elementName 'ApplicationVersion' -textValue "$newMajorMinorBuild.%2a"
272-
Set-XmlNodesElementTextValue -xml $xml -node $propertyGroup -elementName 'ApplicationRevision' -textValue $Revision.ToString()
286+
Set-XmlNodesElementTextValue -xml $xml -node $clickOncePropertyGroup -elementName 'ApplicationVersion' -textValue "$newMajorMinorBuild.%2a"
287+
Set-XmlNodesElementTextValue -xml $xml -node $clickOncePropertyGroup -elementName 'ApplicationRevision' -textValue $revision.ToString()
273288
if ($UpdateMinimumRequiredVersionToCurrentVersion)
274289
{
275-
Set-XmlNodesElementTextValue -xml $xml -node $propertyGroup -elementName 'MinimumRequiredVersion' -textValue "$newVersionNumber"
276-
Set-XmlNodesElementTextValue -xml $xml -node $propertyGroup -elementName 'UpdateRequired' -textValue 'true'
277-
Set-XmlNodesElementTextValue -xml $xml -node $propertyGroup -elementName 'UpdateEnabled' -textValue 'true'
290+
Set-XmlNodesElementTextValue -xml $xml -node $clickOncePropertyGroup -elementName 'MinimumRequiredVersion' -textValue "$newVersionNumber"
291+
Set-XmlNodesElementTextValue -xml $xml -node $clickOncePropertyGroup -elementName 'UpdateRequired' -textValue 'true'
292+
Set-XmlNodesElementTextValue -xml $xml -node $clickOncePropertyGroup -elementName 'UpdateEnabled' -textValue 'true'
278293
}
279294
}
280295

Tests/RunTests.ps1

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Set-StrictMode -Version Latest
55

66
# Clear the screen before running our tests.
7-
cls
7+
Clear-Host
88

99
# Get the directory that this script is in.
1010
$THIS_SCRIPTS_DIRECTORY = Split-Path $script:MyInvocation.MyCommand.Path
@@ -15,17 +15,21 @@ $scriptPath = Join-Path -Path $scriptDirectoryPath -ChildPath 'Set-ProjectFilesC
1515

1616
# Get the path to the project file to use in our tests.
1717
$projectFilePath = Join-Path -Path (Join-Path -Path $THIS_SCRIPTS_DIRECTORY -ChildPath 'TestFiles') -ChildPath 'TestProject.csproj'
18+
$projectFilePathCopy = $projectFilePath + '_UsedByTests_.csproj'
1819

19-
$runScriptExpression = "& $scriptPath -ProjectFilePath $projectFilePath "
20+
# Make a backup of the project file for the tests to run against.
21+
Copy-Item -Path $projectFilePath -Destination $projectFilePathCopy -Force
22+
23+
$global:runScriptExpression = "& $scriptPath -ProjectFilePath $projectFilePathCopy "
2024

2125
function RunScriptWithParameters($parameters)
2226
{
23-
$output = Invoke-Expression "$runScriptExpression $parameters"
27+
Invoke-Expression "$($global:runScriptExpression) $parameters"
2428

2529
}
26-
30+
2731
$testNumber = 0
2832

2933
Write-Host ("{0}. Explicitly set version number..." -f ++$testNumber)
30-
if ((RunScriptWithParameters "-Version 1.2.3.4 -IncrementProjectFilesRevision").EndsWith("'1.2.3.4'.")) { Write-Host "Passed" } else { throw "Test $testNumber failed." }
34+
if ((RunScriptWithParameters "-Version '1.2.3.4'").EndsWith("'1.2.3.4'.")) { Write-Host "Passed" } else { throw "Test $testNumber failed." }
3135

0 commit comments

Comments
 (0)