using wildcards with add-type

This topic contains 5 replies, has 3 voices, and was last updated by  Bill Reid 4 years, 3 months ago.

  • Author
    Posts
  • #9331

    Bill Reid
    Participant

    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

  • #9344

    Poshoholic
    Participant

    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.

  • #9360

    Bill Reid
    Participant

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

  • #9394

    Poshoholic
    Participant

    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?

  • #9406

    Dave Wyatt
    Moderator

    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'"
    
  • #9480

    Bill Reid
    Participant

    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

You must be logged in to reply to this topic.