How To Create a Hook Package
How To Create a Hook Package
Sometimes, you want to do something around a package installation or upgrade. Hook packages are a fairly advanced concept, but they can be really helpful.
In this how-to, we’ll walk through creating install actions in a hook package.
What Is a Hook Package
Hook packages install scripts that are run before or after packaging operations - either triggered by a specific package ID, or by all packages.
Why Use a Hook Package
As with so many things around Chocolatey, the possibilities are endless.
Examples of what you can do with hook packages include:
-
Removing desktop shortcuts that are created during software installation (during any package).
-
Applying configuration to files that are reset during upgrades (during a specific package).
-
Pushing records to a logging endpoint on successful installation (during any package).
-
Packages to clean up specific filetypes to minimise disk space usage (during any package).
-
Packages to display additional information during install or upgrade (during any package).
For more details on hook packages, you can refer to the docs.
Hook Package
Hook packages, similar to extension packages, don’t require many of the files that most Chocolatey packages do.
You will require:
-
A package manifest (
.nuspec
file). -
One or more hook scripts (
.ps1
file(s)), in ahook
directory.
As mentioned above, you can add hook scripts that trigger on specific package IDs or for all packages (also known as a ‘global hook’). This scope is controlled by naming the hook script files that you distribute in the package in specific ways.
The name of the hook script can be broken down into three parts:
pre
orpost
, showing if the script should run before or after a given package script.install
,beforemodify
, oruninstall
, showing which package script the hook should trigger with.all
or a package ID, to create a global hook or run only with specific packages.
NOTE
all
is being used as a magic ID, here, causing the hook to trigger on all packages.
These should be joined with the -
character, and the file should be a valid PowerShell script with the extension .ps1
:
(pre|post)-(install|beforemodify|uninstall)-(all|PackageID).ps1
Examples:
pre-install-all.ps1
would run the script before all install scripts.post-uninstall-jenkins.ps1
would run the script after the Jenkins package uninstall script.
Creating a Hook Package
We’re going to create a basic package that will run on every package install, and display a timestamp so users can easily see how long installs are taking.
NOTE
If you want to publish a hook package to the Chocolatey Community Repository, you should have
.hook
as a package ID suffix.
- Create a new folder for this package. For the example, we will call it
timestamp-example.hook
.- Create a package metadata file named
timestamp-example.hook.nuspec
, and add content as shown below.
- Create a package metadata file named
- In the
timestamp-example.hook
folder, create a folder namedhook
.- Within the
hook
folder, create apre-install-all.ps1
andpost-install-all.ps1
, and add content as shown below.
- Within the
Package Metadata Content
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>timestamp-example.hook</id>
<version>0.1.0</version>
<title>Example Hook (Timestamps)</title>
<authors>__REPLACE__</authors>
<description>A super cool hook package!</description>
<summary>A hook package that displays timestamps before and after installs.</summary>
<tags>hook timestamp package</tags>
</metadata>
<files>
<file src="hook\**" target="hook" />
</files>
</package>
Package PowerShell Content
pre-install-all.ps1
Write-Host "$($env:ChocolateyPackageName): Starting Install at $(Get-Date)"
post-install-all.ps1
Write-Host "$($env:ChocolateyPackageName): Finished Install at $(Get-Date)"
Compiling Your Package
You can now use choco pack
to compile your Chocolatey package, creating a file with a .nupkg
extension, ready for installation!
- In VS Code, press
Ctrl + Shift + P
or use the View menu and click on Command Palette. - Select
Chocolatey: Package Chocolatey package(s)
from the prompt. - Select
timestamp-example.hook.nuspec
from the prompt. - In Additional Arguments enter
--output-directory='~\tutorials'
(or whichever directory you’re using for these tutorials), and press Enter.
You should have a new package generated in your tutorials directory.
Installing Your Package
This sort of package isn’t normally installed on it’s own (as it relies on interaction with other packages), but you can now test installation of your package!
In an elevated PowerShell command prompt, run the following:
choco install timestamp-example.hook --source='tutorials' -y
You should then be able to browse to the hooks directory, within your Chocolatey installation, and see that your PowerShell module has been placed there.
# This should show an 'example' directory, along with all of your other installed extensions
Get-ChildItem $env:ChocolateyInstall\hooks
# This should show your hook script(s)
Get-ChildItem $env:ChocolateyInstall\hooks\timestamp-example
If you now run any choco install
, you should be able to see a timestamp output before and after the installation!
You can then uninstall the hook, if you want, by running the following:
choco uninstall timestamp-example.hook -y
Conclusion
You’ve now created a basic Chocolatey hook package! You can take the knowledge you’ve gained forward, and create some awesome new packages! To see more examples of hook packages, why not have a look at the chocolatey-hooks repository!