Creating your own packages using Chocolatey

Learn creating your own packages using chocolatey with practical examples, diagrams, and best practices. Covers windows, nuget, package-managers development techniques with visual explanations.

Creating Your Own Chocolatey Packages for Windows Software Deployment

Hero image for Creating your own packages using Chocolatey

Learn how to package your applications or custom scripts into Chocolatey packages for easy, automated deployment and management on Windows systems.

Chocolatey is a powerful package manager for Windows, similar to apt or yum on Linux. While it provides access to a vast community repository, there are often scenarios where you need to package your own applications, internal tools, or specific configurations. This article will guide you through the process of creating your own Chocolatey packages, from setting up your environment to building and testing your .nupkg files.

Understanding Chocolatey Package Structure

A Chocolatey package is essentially a NuGet package (.nupkg file) with a specific structure and conventions. It contains metadata about the software, installation scripts, and the software binaries themselves. The core components are the .nuspec file (package metadata) and the tools directory (containing installation/uninstallation scripts and software payload).

flowchart TD
    A[Chocolatey Package (.nupkg)] --> B{Package Metadata (.nuspec)}
    A --> C{Tools Directory}
    C --> D[chocolateyInstall.ps1]
    C --> E[chocolateyUninstall.ps1]
    C --> F[Software Binaries/Installers]
    B --"Describes"--> A
    C --"Contains"--> D
    C --"Contains"--> E
    C --"Contains"--> F

Basic structure of a Chocolatey package

Setting Up Your Development Environment

Before you can create packages, you need a few prerequisites. Ensure you have Chocolatey installed, and then you'll use the choco new command to scaffold a new package. This command generates the basic directory structure and template files, saving you time.

1. Install Chocolatey

If you don't have Chocolatey installed, open an administrative PowerShell and run the installation command from the official Chocolatey website.

2. Create a New Package Template

Navigate to your desired package development directory in PowerShell and run choco new <package_name>. Replace <package_name> with a unique identifier for your software (e.g., my-custom-app). This will create a folder with the package name and populate it with template files.

3. Review Generated Files

Explore the newly created directory. You'll find _rels, package.nuspec, and a tools folder containing chocolateyInstall.ps1, chocolateyUninstall.ps1, and VERIFICATION.txt.

Customizing Your Package: The .nuspec and PowerShell Scripts

The heart of your package lies in the .nuspec file and the PowerShell scripts. The .nuspec defines metadata like package ID, version, authors, and dependencies. The PowerShell scripts (chocolateyInstall.ps1 and chocolateyUninstall.ps1) handle the actual installation and uninstallation logic.

Editing the .nuspec File

Open the <package_name>.nuspec file. You'll need to update fields like <id>, <version>, <title>, <authors>, <description>, and <tags>. Pay close attention to the <dependencies> section if your software requires other Chocolatey packages.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
  <metadata>
    <id>my-custom-app</id>
    <version>1.0.0</version>
    <title>My Custom Application</title>
    <authors>Your Name</authors>
    <owners>Your Organization</owners>
    <projectUrl>https://your-project-url.com</projectUrl>
    <iconUrl>https://your-project-url.com/icon.png</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>This is a custom application packaged with Chocolatey.</description>
    <summary>A custom application for internal use.</summary>
    <tags>custom internal app</tags>
    <dependencies>
      <dependency id="dotnetfx" version="[4.8,]" />
    </dependencies>
  </metadata>
  <files>
    <file src="tools\**" target="tools" />
  </files>
</package>

Example of a customized .nuspec file

Writing chocolateyInstall.ps1

This script is executed when the package is installed. It should handle downloading the software (if not included directly), performing checksum validation, and running the installer silently. For simple applications, you might just copy files or run an MSI.

$ErrorActionPreference = 'Stop'

$packageName = 'my-custom-app'
$fileType = 'exe'
$url = 'https://your-internal-server.com/MyCustomAppInstaller.exe'
$url64 = 'https://your-internal-server.com/MyCustomAppInstaller64.exe'
$checksum = 'A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2'
$checksum64 = 'B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F7A8B9B0C1D2E3F4A5B6C7D8E9F0A1B2'

$installArgs = "/S /INSTALLDIR=`"$($env:ProgramFiles)\MyCustomApp`""

# Download and install the software
Install-ChocolateyInstallPackage -PackageName $packageName \
                                 -FileType $fileType \
                                 -Url $url \
                                 -Url64bit $url64 \
                                 -Checksum $checksum \
                                 -ChecksumType 'sha256' \
                                 -Checksum64bit $checksum64 \
                                 -ChecksumType64bit 'sha256' \
                                 -SilentArgs $installArgs

# Example for a zip file payload included in the package
# $toolsDir = $(Split-Path -parent $MyInvocation.MyCommand.Definition)
# Install-ChocolateyZipPackage -PackageName $packageName -Url "$toolsDir\MyCustomApp.zip" -UnzipLocation "$($env:ProgramFiles)\MyCustomApp"

Example chocolateyInstall.ps1 for an external installer

Writing chocolateyUninstall.ps1

This script handles the uninstallation process. It should silently remove the software installed by chocolateyInstall.ps1. Use Uninstall-ChocolateyPackage for MSI/EXE uninstallers.

$ErrorActionPreference = 'Stop'

$packageName = 'my-custom-app'

# Get the uninstall string from the registry
$uninstallString = Get-UninstallRegistryKey -SoftwareName 'My Custom Application' | Select-Object -ExpandProperty UninstallString

# Uninstall the software silently
Uninstall-ChocolateyPackage -PackageName $packageName -SilentArgs "/S" -InstallerType 'exe' -UninstallString $uninstallString

Example chocolateyUninstall.ps1

Building and Testing Your Package

Once your .nuspec and PowerShell scripts are ready, you can build your package into a .nupkg file. After building, it's crucial to test the installation and uninstallation processes thoroughly.

1. Build the Package

Navigate to the root directory of your package (where the .nuspec file is located) in PowerShell and run choco pack. This will create the .nupkg file in the same directory.

2. Install the Package Locally

To test, you can install the package directly from the .nupkg file. Run choco install <package_name> --source "'./'" (or the full path to your .nupkg file). The --source "'./'" tells Chocolatey to look in the current directory.

3. Verify Installation

Check if the application was installed correctly, if shortcuts were created, and if it functions as expected. You can also run choco list --local-only to see if your package is listed.

4. Uninstall the Package

Test the uninstallation by running choco uninstall <package_name>. Verify that the application is completely removed and no residual files or registry entries remain.

Creating your own Chocolatey packages empowers you to streamline software deployment and management within your organization or for your personal projects. By following these steps and leveraging Chocolatey's robust helper functions, you can create reliable and maintainable packages.