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="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>vlc_mb</id>
    <title>VLC media player</title>
    <version>2.0.8</version>
    <authors>VideoLAN</authors>
    <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>
    <projectUrl>https://videolan.org/vlc/</projectUrl>
    <tags>vlc media player music video streaming multicast</tags>
    <copyright>GNU General Public License v2</copyright>
    <licenseUrl>https://gnu.org/licenses/gpl.html</licenseUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <!--<iconUrl>https://raw.github.com/test repo/master/vlc_mb/vlc_mb.png</iconUrl>-->
    <!--<dependencies>
      <dependency id="" version="" />
    </dependencies>-->
    <releaseNotes>This chocolatey package is configured to install VLC Media Player using the Nullsoft installer in silent mode.</releaseNotes>
  </metadata>
  <files>
    <file src="tools\**" target="tools" />
    <!--<file src="content\**" target="content" />-->
  </files>
</package>

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 = 'https://get.videolan.org/vlc/2.0.8/win32/vlc-2.0.8-win32.exe'
$url64 = 'http://download.videolan.org/pub/videolan/vlc/last/win64/vlc-2.0.8-win64.exe'
$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)
{
	try{
		switch ($regtree)
		{
			#constant uints for registry trees
			HKCR { $regtree = "&h80000000" }
			HKCU { $regtree = "&h80000001" }
			HKLM { $regtree = "&h80000002" }
			HKU { $regtree = "&h80000003" }
			#more obscure trees: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724836%28v=vs.85%29.aspx
			HKPerformanceData { $regtree = "&h80000004" } # http://msdn.microsoft.com/en-us/library/windows/desktop/aa373219%28v=vs.85%29.aspx
			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.
			return
		}
		
		$objLocator = New-Object -COM "Wbemscripting.SWbemLocator"
		$objServices = $objLocator.ConnectServer($computername,"root\default","","","","","",$objNamedValueSet)
		$objStdRegProv = $objServices.Get("StdRegProv")
		$Inparams = ($objStdRegProv.Methods_ | where {$_.name -eq "GetStringValue"}).InParameters.SpawnInstance_()
		($Inparams.Properties_ | where {$_.name -eq "Hdefkey"}).Value = $regtree
		($Inparams.Properties_ | where {$_.name -eq "Ssubkeyname"}).Value = $regkey
		($Inparams.Properties_ | where {$_.name -eq "Svaluename"}).Value = $value
		#write-host querying string value HKLM $regkey : $value

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

$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
}
else
{
write-host Failure to obtain uninstallstring value for VLC media player.
return
}

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

cd %chocolateyinstall%\chocolateytemplates\_templates\vlc_mb
cpack

Test the package install:
Without getting too complex with nuget.server asp.net 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'
pause
chocolatey -debug install vlc_mb -source '%systemdrive%\nupkgs'
pause
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:

WordPress.com Logo

You are commenting using your WordPress.com 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: