Creating a Self-Updating Chocolatey Package
More and more applications ship with an automatic update mechanisms, which
downloads new versions of the application as soon as they are available. A
command line option such as myapp.exe --update looks nice, but the update
process is tricky, as we cannot simply replace the application while its
running.
A very minimalist approach, which can work for command line tools, relies on the Chocolatey package manager. Here's an example:
Package structure:
myapp.nuspectools\chocolateyInstall.ps1chocolateyUninstall.ps1myapp.zip(which contains amyapp.exefile)
chocolateyInstall.ps1:
$ErrorActionPreference = 'Stop' $toolsDir = (Split-Path -parent $MyInvocation.MyCommand.Definition) $zipFile = Join-Path $toolsDir 'myapp.zip' $batShimFile = Join-Path $env:ChocolateyInstall 'bin\myapp.bat' $ps1ShimFile = Join-Path $env:ChocolateyInstall 'bin\myapp.ps1' $appDir = "C:\SomeFolder\$($env:ChocolateyPackageName)\$($env:ChocolateyPackageVersion)" $appFile = Join-Path $appDir 'myapp.exe' Get-ChocolateyUnzip -FileFullPath $zipFile -Destination $appDir Set-Content -Path $batShimFile -Value "@echo off~ncall ~"$appFile~" %*" -Force Set-Content -Path $ps1ShimFile -Value "& '$appFile' ~$args" -Force
chocolateyUninstall.ps1:
$ErrorActionPreference = 'Stop'
$batShimFile = Join-Path $env:ChocolateyInstall 'bin\myapp.bat'
if (Test-Path $batShimFile) {
Remove-Item $batShimFile -Force
}
$ps1ShimFile = Join-Path $env:ChocolateyInstall 'bin\myapp.ps1'
if (Test-Path $ps1ShimFile) {
Remove-Item $ps1ShimFile -Force
}
$appDir = "C:\SomeFolder\$($env:ChocolateyPackageName)"
if (Test-Path $appDir) {
Remove-Item $appDir -Recurse -Force
}
The technique works like this:
- Calling
choco install myappinstalls themyapp.zipfile to the Chocolatey lib directory ($env:ChocolateyInstall\lib\myapp\tools) and extracts the archive toC:\SomeFolder\myapp\1.0.0\ - The install script creates a cmd and a Powershell file, which point to
C:\SomeFolder\myapp\1.0.0\myapp.exe - The application can now be called in PowerShell and cmd by typing
myapp - We can now update the application using
choco upgrade myapp, even while it is running. The batch file will point to the new version (e.g.C:\SomeFolder\myapp\2.0.0\myapp.exe), which will work for any future calls tomyapp