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.


Posted 08-25-2010 8:04 PM by Christopher Bennage

[Advertisement]

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)