Apt Windows: Let’s Get Chocolatey! Part 2 : Multiple Installs and Package Creation

Chocolatey is a global automation tool that makes use of the NuGet package management system. It is an advanced packaging tool that makes use of PowerShell to allow you to do virtually anything on a Windows system. The main use of Chocolatey is to install applications and tools silently on your machine. This makes it a machine package manager with a Windows flavour.

In the previous article, we installed Chocolatey and started using it to install applications and keep our system up to date. In this article, we will focus on more advanced installs, setting up a development environment with a simple script and creating your own chocolatey packages.

Installing Multiple Applications

If you’re familiar with the installer program for the application in your package, you can use Chocolatey to pass it any arguments / switches to customize the package install. For example, let’s take the scenario where you’re building a package for CruiseControl.NET and want to override its install directory from %programfiles%\ccnet to c:\ccnet. To do this, you just call cinst like so:

c:\> cinst cruisecontrol.net –override –installArguments ""/S /D=c:\ccnet""

Note the double quotes passed with install arguments. This handles the stripping of quotes off when PowerShell is called and passed these arguments.

In addition to installing the regular way, you can also use a packages.config file to create a list of packages to install in one go. The xml format used in packages.config is similar to that used in NuGet packages but with an additional source attribute. This has the same purpose as the -source argument for cinst, allowing you to specify a package source server other than chocolatey to inspect and install from. In the following packages.config file for instance, we specify Microsoft's Web Platform Installer (webpi) server as the source for the IIS Express package. You can webpi, ruby, cygwin, or any custom source you have for chocolatey to inspect and install from.

<?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="apackage" />
      <package id="anotherPackage" version="1.1" />
      <package id="iisexpress" version="8.0" source="webpi" />
      <package id="arubygem" source="ruby" />
      <package id="cruisecontrol.net" />
    </packages>

To have chocolatey install the five packages listed in packages.config, you just point cinst at packages.config:

c:\> cinst ..\setup\packages.config

Chocolatey will then install the packages in the order they are listed. If one package has dependencies on other packages they will be installed before the other packages no matter what order the packages get downloaded in.

Installing All The Packages On a Custom Source

Perhaps one of the best ways to really bootstrap your machine is not to keep a packages.config around at all and instead keep all the packages you want to install in the cloud. If you were to set up a custom source with packages as you would on myget.org you could call cinst all to install every package at that source:

c:\> cinst all -source http://somewhere/packages

Note that you may not do this with the chocolatey or nuget sources because that would be a very expensive operation and could take a very, very long time to complete. And you probably don’t want everything on the nuget source server anyway, do you?

Setting Up a Development Environment

Perhaps one of the most useful applications for Chocolatey is its potential to set up a base development environment on a machine for a project. Team leads or server admins can now write a simple powershell script to install the same tools and create the same working directories for new development machines rather than a simple readme file with a list of steps for new developers to follow. Similarly the same script could see what was already installed on the machine and just add the missing packages. All with one command line call.

For example, here's a powershell script that will first install Chocolatey, and then use that to install NuGet, Ruby, Ruby DevKit and update gems if they are't already installed.

function Install-NeededFor {
param([string]$packageName = '')
  if ($packageName -eq '') {return $false}

  $yes = '6'
  $no = '7'
  $msgBoxTimeout='-1'

  $answer = $msgBoxTimeout
  try {
    $timeout = 10
    $question = "Do you need to install $($packageName)? Defaults to 'Yes' after $timeout seconds"
    $msgBox = New-Object -ComObject WScript.Shell
    $answer = $msgBox.Popup($question, $timeout, "Install $packageName", 0x4)
  }
  catch {
  }

  if ($answer -eq $yes -or $answer -eq $msgBoxTimeout) {
    write-host 'returning true'
    return $true
  }
  return $false
}

#install chocolatey
if (Install-NeededFor 'chocolatey') {
  iex ((new-object net.webclient).DownloadString('http://bit.ly/psChocInstall')) 
}

# install nuget, ruby.devkit, and ruby if they are missing
cinstm nuget.commandline

if (Install-NeededFor 'ruby / ruby devkit') {
  cinstm ruby.devkit
  #cinstm ruby #devkit install will automatically install ruby
}

#perform ruby updates and get gems
gem update --system
gem install rake
gem install bundler

To run the script, you'll need a simple setup.cmd file:

@echo off
SET DIR=%~dp0%
@PowerShell -NoProfile -ExecutionPolicy unrestricted -Command "& '%DIR%setup.ps1' %*"
pause

Just make sure to make it obvious in a readme file or something similar that running setup.cd is all that needs to be done.

Create Your Own Chocolatey Packages

Creating a package is super simple. Here’s what you need:

  • Nuspec (nuget specification file for a .nupkg file)
  • Executable(s) and/or a PowerShell script file named chocolateyinstall.ps1

It’s really that easy. You fill out the informational aspects of your package in the nuspec. If you have an executable you want to include in the package, you just drop that into the package and you are done. Chocolatey will find that executable and create a batch file that is on the path referencing that executable.

If you need to download a zip, executable, MSI, or something else, then you create a chocolateyInstall.ps1 file where the power of PowerShell and Chocolatey comes in. PowerShell gives you a scripting environment with the full power of the .NET framework. You can set ACLs, download files, etc. With PowerShell you can do anything you can do in .NET. When it comes to Chocolatey, you are automating instructions for installing and/or configuring an application. The PS1 file is just a set of instructions on how to download and "install" an application/tool on a machine. There are built-in helpers that really help with reducing the amount of work that you need to do. Take a look at the following:

Install-ChocolateyPackage 'notepadplusplus' 'exe' '/S' 'http://download.tuxfamily.org/notepadplus/5.9/npp.5.9.Installer.exe'

That one line of PowerShell invokes a chocolatey function that knows how to download an installer and call silent arguments during installation/upgrade. For a full list of helpers and commands for your packages, have a look here for more information: https://github.com/chocolatey/chocolatey/wiki/CreatePackages.

Conclusion

In this article, you've looked at several scenarios in which Chocolatey is used to install multiple packages with a minimum of effort on your part

  • You can write a local packages.config file listing all the packages to install.
  • You can create your own custom package source server and have chocolatey install all the packages located there.
  • You can write a powershell script to install chocolatey and then use it to create a development environment, installing packages if needed, setting up directories and so on.

You've also seen the basics of creating your own Chocolatey package using nuspec and Chocolatey itself.

Chocolatey is young but it has power and simplicity built into it. It has a community that is rapidly growing. This is not the first time someone has tried to bring ideas of apt-get to Windows and it may not be the last. Chocolatey has a high chance of succeeding where others have failed because simplicity is a central concept. Chocolatey is simple to use, simple to create / maintain packages, and simple to update.

If you want to get involved with Chocolatey, start by learning about it on http://chocolatey.org and by reading the documentation on github. You can also get involved with the discussion on the Chocolatey google group.

Let’s Get Chocolatey!

You might also like...

Comments

About the author

Rob Reynolds

Rob Reynolds United States

Rob Reynolds has been programming in .NET since the early days of 1.0. In his day job he drinks beer and tries to get creative at a digital marketing agency. Rob is a C# MVP, ASPInsider, C# Insi...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Java is to JavaScript what Car is to Carpet.” - Chris Heilmann