using wildcards with add-type

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

  • Author
    Posts
  • #9331
    Profile photo of Bill Reid
    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
    Profile photo of Poshoholic
    Poshoholic
    Member

    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
    Profile photo of Bill Reid
    Bill Reid
    Participant

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

  • #9394
    Profile photo of Poshoholic
    Poshoholic
    Member

    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
    Profile photo of Dave Wyatt
    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
    Profile photo of Bill Reid
    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.