# encoding: ascii
# api: powershell
# title: Import-NugetLibrary
# description: (Install and) load the assemblies from a NuGet package into PowerShell
# version: 4.0
# type: module
# author: Joel Bennett
# license: CC0
# function: Import-NugetLibrary
# x-poshcode-id: 6300
# x-archived: 2016-06-17T08:47:46
# x-published: 2016-04-12T03:14:00
#
#
#requires -Module PackageManagement
function Import-NugetLibrary {
param(
[Parameter(Mandatory)]
[String]$Name,
[String]$Destination = "$(Split-Path $Profile)\Libraries"
)
$ErrorActionPreference = "Stop"
if(!(Test-Path $Destination -Type Container)) {
throw "The destination path ($Destination) must point to an existing folder, NuGet will install packages in subdirectories of this folder."
}
# Normalize: nuget requires destination NOT end with a slash
$Destination = (Convert-Path $Destination).TrimEnd("\")
$Package = Install-Package -Name $Name -Destination $Destination -ProviderName NuGet -Source 'https://www.nuget.org/api/v2' -ExcludeVersion -PackageSaveMode nuspec -Force
$PackagePath = "$Destination\$Name"
# Nuget packages hide their assemblies in folders with version numbers...
if($PSVersionTable.PSVersion -ge "4.0") {
$Versions = "net46","net452","net451","net45","net40","net35","net20"
}elseif($PSVersionTable.PSVersion -ge "3.0") {
$Versions = "net40","net35","net20","net45","net451","net452","net46"
}else {
$Versions = "net35","net20"
}
# build full path with \ on the end
$LibraryPath = ($Versions -replace "^", "$PackagePath\lib\") + "$PackagePath\lib\" + "$PackagePath" |
# find the first one that exists
Convert-Path -ErrorAction SilentlyContinue | Select -First 1
$Number = $LibraryPath -replace '.*?([\d\.]+)','$1' -replace '(?<=\d)(?=\d)','.'
$References = ([xml](gc "$PackagePath\$Name.nuspec")).package.metadata.references
# If there's no references node, this is an old package, just reference everything we found
if(!$References) {
$Assemblies = Get-ChildItem $LibraryPath -Filter *.dll
} else {
$group = $references.Group | where { $_.targetFramework.EndsWith($number) }
if($group) {
$Files = $group.reference.File
} else {
# If we can't figure out the right group, just get all the references:
$Files = @($references.SelectNodes("//*[name(.) = 'reference']").File | Select -Unique)
}
$Assemblies = Get-Item ($Files -replace "^", "$LibraryPath\")
}
# Just for the purpose of the verbose output
Push-Location $Destination
# since we don't know the order, we'll just loop a few times
for($e=0; $e -lt $Assemblies.Count; $e++) {
$success = $true
foreach($assm in $Assemblies) {
Write-Verbose "Import Library $(Resolve-Path $Assm.FullName -Relative)"
Add-Type -Path $Assm.FullName -ErrorAction SilentlyContinue -ErrorVariable failure
if($failure) {
$success = $false
} else {
Write-Host "LOADING: " -Fore Cyan -NoNewline
Write-Host $LibraryPath\ -Fore Yellow -NoNewline
Write-Host $Assm.Name -Fore White
}
}
# if we loaded everything ok, we're done
if($success) { break }
}
Pop-Location
if(!$success) { throw $failure }
return
}