Part 2b: Creating a nupkg to distribute an installable package in a EXE

Please refer to Building Packages to form the proper template before continuing.


Create the Package config:

cd %chocolateyinstall%\chocolateytemplates\_templates
warmup chocolatey vlc_mb
cd vlc_mb

Edit the package config:
You will edit the nuspec file, which is generally the same as the nuget nuspec specifications, except for the additional “source” parameter.
Beware of common mistakes.

cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb
notepad vlc_mb.nuspec

A few things should already be specified, but we will modify a few other things.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="">
    <title>VLC media player</title>
    <owners>Matt Brown</owners>
    <summary>VLC is a free and open source cross-platform multimedia player and framework that plays most multimedia files as well as DVD, Audio CD, VCD, and various streaming protocols.</summary>
    <description>VLC media player</description>
    <tags>vlc media player music video streaming multicast</tags>
    <copyright>GNU General Public License v2</copyright>
    <!--<iconUrl> repo/master/vlc_mb/vlc_mb.png</iconUrl>-->
      <dependency id="" version="" />
    <releaseNotes>This chocolatey package is configured to install VLC Media Player using the Nullsoft installer in silent mode.</releaseNotes>
    <file src="tools\**" target="tools" />
    <!--<file src="content\**" target="content" />-->

Create the installation and uninstallation scripts:

Edit the powershell install script:
The chocolateyInstall.ps1 powershell script is what’s executed by chocolatey when an install occurs.
The script helper reference will assist you when dealing with the chocolateyInstall.ps1 powershell script.

cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb
notepad .\tools\chocolateyInstall.ps1

Make note of some of the interesting things:
1) This is an installable application.
2) It is an EXE.
3) This EXE is a NSIS package and is installable.

$packageName = 'vlc_mb'
$installerType = 'EXE'
$url = ''
$url64 = ''
$silentArgs = '/S' # a quick google turned this up
$validExitCodes = @(0)
Install-ChocolateyPackage "$packageName" "$installerType" "$silentArgs" "$url" "$url64"  -validExitCodes $validExitCodes

Edit the powershell uninstall script:
Although not contained in the template, in order to allow users to utilize the `chocolatey uninstall` command for a package, you must include a `chocolateyUninstall.ps1` script within the package.

Due to the way the 32-bit virtualization works on 64-bit Windows systems, there are, in essence, two registries, one for 32-bit processes, and one for 64-bit processes. In order to take care of this problem, I have modified a script I located on the Internet for querying of the registry and included it within the chocolateyUninstall.ps1.

You can utilize it within the chocolateyUninstall.ps1 script:

cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb
notepad .\tools\chocolateyUninstall.ps1

There are two helper scripts that are included (as of August), but aren’t really rolled into the main parts of code yet: `Uninstall-ChocolateyPackage.ps1` and `UnInstall-ChocolateyZipPackage.ps1`. So, do not use them (yet).

Function GetValueFromRegistryThruWMI($providerarchtoget, [string]$computername, $regtree, $regkey, $value)
		switch ($regtree)
			#constant uints for registry trees
			HKCR { $regtree = "&h80000000" }
			HKCU { $regtree = "&h80000001" }
			HKLM { $regtree = "&h80000002" }
			HKU { $regtree = "&h80000003" }
			#more obscure trees:
			HKPerformanceData { $regtree = "&h80000004" } #
			HKCurrentConfig { $regtree = "&h80000005" }
			HKCULocalSettings { $regtree = "&h80000007" }
			default { $regtree = "&h80000002" }

		$objNamedValueSet = New-Object -COM "WbemScripting.SWbemNamedValueSet"
		if ( $providerarchtoget -eq 32 ) {
			if ( [IntPtr]::size -eq 8 -and (test-path env:\PROCESSOR_ARCHITEW6432) ) {
				#write-host process arch is 64-bit, querying 32-bit provider as requested.
				$objNamedValueSet.Add("__ProviderArchitecture", 32) | Out-Null
			elseif ( [IntPtr]::size -eq 4 ) {
				#write-host process arch is 32-bit, querying 32-bit provider.
				$objNamedValueSet.Add("__ProviderArchitecture", 32) | Out-Null
		elseif ( $providerarchtoget -eq 64 ) {
			if ( [IntPtr]::size -eq 8 -and (test-path env:\PROCESSOR_ARCHITEW6432) ) {
				#write-host process arch is 64-bit, querying 64-bit provider as requested.
				$objNamedValueSet.Add("__ProviderArchitecture", 64) | Out-Null
			elseif ( [IntPtr]::size -eq 4 ) {
				#write-host process arch is 32-bit, querying 64-bit provider.
				$objNamedValueSet.Add("__ProviderArchitecture", 64) | Out-Null
		else {
			#write-host You have requested an architecture that is not handled.  Please provide "32" or "64" as your first parameter.
		$objLocator = New-Object -COM "Wbemscripting.SWbemLocator"
		$objServices = $objLocator.ConnectServer($computername,"root\default","","","","","",$objNamedValueSet)
		$objStdRegProv = $objServices.Get("StdRegProv")
		$Inparams = ($objStdRegProv.Methods_ | where {$ -eq "GetStringValue"}).InParameters.SpawnInstance_()
		($Inparams.Properties_ | where {$ -eq "Hdefkey"}).Value = $regtree
		($Inparams.Properties_ | where {$ -eq "Ssubkeyname"}).Value = $regkey
		($Inparams.Properties_ | where {$ -eq "Svaluename"}).Value = $value
		#write-host querying string value HKLM $regkey : $value

		$Outparams = $objStdRegProv.ExecMethod_("GetStringValue", $Inparams, "", $objNamedValueSet)
		if (($Outparams.Properties_ | where {$ -eq "ReturnValue"}).Value -eq 0)
		$result = ($Outparams.Properties_ | where {$ -eq "sValue"}).Value
		return $result
		return $false
	catch {

$packageName = 'vlc_mb'
$fileType = 'EXE'
$silentArgs = '/S' # a quick google turned this up
$filePath = ''
#not ready as of September 9th, 2013:
#Uninstall-ChocolateyPackage $packageName $fileType $silentArgs $filePath
#for NSIS, obtain the UninstallString from the registry, as it should have been created and execute it
#we have to consider 64-bit systems, and the fact that the Uninstall key is virtualized for access on their own systems.
#query the 64-bit arch first... this will return a value when the powershell.exe process is running as 64 or 32-bit:
$filePath = GetValueFromRegistryThruWMI "64" "." "HKLM" "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\VLC media player" "UninstallString"
#query the 32-bit arch... this will return a value when the powershell.exe process is running as
if ( $filepath.length -eq 0 ) {
$filePath = GetValueFromRegistryThruWMI "32" "." "HKLM" "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\VLC media player" "UninstallString"

if ( $filepath ) {
& "$filePath" $silentArgs
write-host Failure to obtain uninstallstring value for VLC media player.

Build the package:
All packages are a nuget package (nupkg). Chocolatey includes a batch to build nuget packages:

cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb

Test the package install:
Without getting too complex with nuget.server instances, you can simply use any directory that is accessible (including anything accessible via a device redirector, like CIFS, NFS, etc):

mkdir %systemdrive%\nupkgs
cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb
copy vlc_mb.*.nupkg %systemdrive%\nupkgs\
cd %userprofile%
chocolatey list -source '%systemdrive%\nupkgs'
chocolatey search video -source '%systemdrive%\nupkgs'
chocolatey search music player -source '%systemdrive%\nupkgs'
chocolatey -debug install vlc_mb -source '%systemdrive%\nupkgs'
chocolatey version all -lo

Test the package uninstall:

chocolatey version all -lo
chocolatey -debug uninstall vlc_mb

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: