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.nuspec
tools\
chocolateyInstall.ps1
chocolateyUninstall.ps1
myapp.zip
(which contains amyapp.exe
file)
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 myapp
installs themyapp.zip
file 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