Over a million developers have joined DZone.

PowerShell, GAC, and build servers

·
I’m still a Powershell n00b, so take my advice cum granis salis.

No GacUtil Please

My situation was that I needed some 3rd party assemblies installed in the GAC on a build server. There was a little bit of churn on the assemblies, so it wasn’t just an “install once and forget”. I’m lazy, so I found a powershell script to help me out. I wanted to be able to run the script and have it install all the assemblies from the current folder in the GAC. Here is my end result:

if ( $null -eq ([AppDomain]::CurrentDomain.GetAssemblies() |? { $_.FullName -eq "System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" }) ) {
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") | Out-Null
}

$publish = New-Object System.EnterpriseServices.Internal.Publish

Foreach ($file in Get-Childitem "*.dll" -recurse -force)
{
Write-Host $file

$assembly = $null

if ( $file -is [string] ) {
$assembly = $file
} elseif ( $file -is [System.IO.FileInfo] ) {
$assembly = $file.FullName
} elseif ( $file -is [System.IO.DirectoryInfo] ) {
Continue
} else {
#throw ("The object type '{0}' is not supported." -f $file.GetType().FullName)
}

if ( -not (Test-Path $assembly -type Leaf) ) {
throw "The assembly '$assembly' does not exist."
}

if ( [System.Reflection.Assembly]::LoadFile( $assembly ).GetName().GetPublicKey().Length -eq 0 ) {
throw "The assembly '$assembly' must be strongly signed."
}

Write-Output "Installing: $assembly"

$publish.GacInstall( $assembly )
}

Ye Olde Default Runtime

You might notice that this script is using some .NET 4.0 assemblies. Well, Powershell runs against the .NET 2.0 runtime. So executing this script will give you an error that contains this:

“This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.”

Crackers.

You can get the Powershell to use the latest runtime by hacking some registry settings. I hacked away and the script executed just fine.

reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1

N.B. I had to restart for these changes to take effect.

An Unforeseen Consequence

As is mentioned here, making this change to your registry can be a really bad idea. In fact, I ended having a problem where I was unable to compile a particular project due to making this change. I wasted an hour examining the code before I understand what the problem actually was. (Unfortunately, I failed to document the error.)

I advise against changing the registry and recommend sticking with the config file.

Topics:

Published at DZone with permission of Christopher Bennage, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}