Author Posts

August 12, 2013 at 5:44 am

I trying to load a dll that is installed in the gac but want to be able to specify just the major version in the assembly name parameter. like this
$wpname="assemName, Version=6.*, Culture=neutral, PublicKeyToken=be44eff3c954219b"
or
$wpname="assemName, Version=6.*.*.*, Culture=neutral, PublicKeyToken=be44eff3c954219b"

I use this in a .psm1 file and want to be able to patch the dll with a new minor version without having to burden users with finding and replacing all the .psm1 files as well.

When I look at the doc for addtype it says it accepts wildcards for the name, but I suspect that means only for the standard windows dll's.

is this possible? or am I just wasting my time?

thanks

August 12, 2013 at 8:16 am

Have you thought about using [System.Reflection.Assembly]::LoadWithPartialName to load the assembly? Or you could use Add-Type and use the path to the file on disk since that probably shouldn't change (or ideally it would be discoverable using the Registry)?

As far as I know, wildcards for the name are actually for when you are using a path, not a full assembly name.

August 12, 2013 at 12:58 pm

Thanks, I was originally going to use LoadWithpartialName, but read that it was being deprecated.

August 13, 2013 at 4:27 am

Yeah, that command has been in the "being deprecated" state for a while. I've used it in a pinch when nothing else seemed to present a better option though. What about the second question for Add-Type. Can you Add-Type your dll using a path that can be determined programmatically?

August 13, 2013 at 5:32 am

You can enumerate the GAC and do your own pattern matching to find the actual assembly name. It looks like you either need to use P/Invoke to call methods of the native GAC API for that, or have a copy of gacutil.exe available for your PowerShell script to call. Here's what I tried on my machine as a test. Sorry if it's a little hard to read; I have a love affair with regular expressions. 😛

The important thing is that the pattern matches the entire string returned by gacutil (which is why I have the ".*" right before the closing parenthesis in the regex pattern, and the pattern begins and ends with ^ $). In this case, I chose to extract the text without any leading or trailing whitespace, as well (which is what the parentheses are for, and why I'm using $matches[1] instead of $matches[0]).

$assemblyRegex = '^\s*(' + 
                 'WebMatrix.Data\s*,' +
                 '\s*Version\s*=\s*2\..*\..*\..*\s*,' + 
                 '\s*Culture\s*=\s*neutral\s*,' + 
                 '\s*PublicKeyToken\s*=\s*31bf3856ad364e35' +
                 '.*)\s*$'

Set-Location -Path 'C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools'

$assemblyName = ""

$assemblies = .\gacutil.exe /L

foreach ($assembly in $assemblies)
{
    if ($assembly -match $assemblyRegex)
    {
        $assemblyName = $matches[1]
        break
    }
}

Write-Host "Detected assembly name: '$assemblyName'"

August 14, 2013 at 9:31 am

thanks Dave and Poshoholic, I think I can use something based on your comments. I can use Get-Child to search the gac ( c:\windows\assembly ) for my assembly, then use the path option to load it if it is found. I am going to search to make sure I can safely assume that the gac is always going to be c:\windows\assembly and if not how to get that starting location for the get-child search