Nuget Update-Package incorrectly updating assembly binding redirects

后端 未结 3 455
夕颜
夕颜 2020-12-14 19:18

I have an internal NuGet package that contains a single dll, no external NuGet package dependencies, and no web.config transforms.

Yet when i run Update-Package on m

相关标签:
3条回答
  • 2020-12-14 19:44

    Skip applying binding redirects is an option now in NuGet 3.3.0: Issue #1147

    0 讨论(0)
  • 2020-12-14 19:48

    Use following command in Package Manager Console

    PM> Get-Project –All | Add-BindingRedirect

    Refer https://weblog.west-wind.com/posts/2014/nov/29/updating-assembly-redirects-with-nuget for detailed explanation.

    0 讨论(0)
  • 2020-12-14 20:00

    I have a better solution. Because I gets absolutely crazy when I have to update over 72 references everytime I update my packages, I've developed a PowerShell script that updates your Web.Config based on the packages in your packages.config and the DLLs you have published in the BIN directory.

    param (
        [Parameter(Mandatory=$false)]
        [string] $webConfigPath,
        [string] $packagesConfigPath,
        [string] $binPath
    )
    
    [bool]$isWindowsFormsAssemblyLoaded = $false
    [System.Xml.Linq.XNamespace]$ns1 = "urn:schemas-microsoft-com:asm.v1"
    
    function ClearBindings([System.Xml.Linq.XDocument] $xml) {
    
        $elements = $xml.Root.Element("runtime").Element($ns1 + "assemblyBinding").Elements()
        $l1 = New-Object "System.Collections.Generic.List[System.Xml.Linq.XElement]"
        $l1.AddRange($elements)
    
        $l1 | ForEach-Object { $_.Remove() }
    }
    function GetPackageList([System.Xml.Linq.XDocument] $xml, [string] $binPath) {
    
        $elements = $xml.Root.Elements("package")
        $l1 = New-Object "System.Collections.Generic.List[System.Xml.Linq.XElement]"
        $l1.AddRange($elements)
    
        [System.Collections.Generic.List[string]]$packageList = New-Object "System.Collections.Generic.List[string]"
        $l1 | ForEach-Object { $packageList.Add("$binPath\" + $_.Attribute("id").Value + ".dll") }
        return $packageList
    }
    function ExtractPublicKey([System.Reflection.Assembly]$asm) {
        $bytes = $asm.GetName().GetPublicKeyToken()
        return [System.BitConverter]::ToString($bytes).Replace("-", "")
    }
    function ExtractCulterInfoName($asm) {
        if ($asm.GetName().CultureInfo.TextInfo.CultureName -eq "") {
            return "neutral"
        } else {
            return $asm.GetName().CultureInfo.TextInfo.CultureName
        }
    }
    function CreateBindingElement([System.IO.FileInfo] $fi) {
    
        [System.Reflection.Assembly]$asm = [System.Reflection.Assembly]::LoadFile($fi.FullName)
        $publicKey = ExtractPublicKey $asm
        $culterInfo = ExtractCulterInfoName $asm
    
        $assemblyIdentity = [System.Xml.Linq.XElement]::new($ns1 + "assemblyIdentity")
        $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("name", $asm.GetName().Name))
        $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("publicKeyToken", $publicKey))
        $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("culture", $culterInfo))
    
        $bindingRedirect = [System.Xml.Linq.XElement]::new($ns1 + "bindingRedirect")
        $bindingRedirect.Add([System.Xml.Linq.XAttribute]::new("oldVersion", "0.0.0.0-65535.65535.65535.65535"))
        $bindingRedirect.Add([System.Xml.Linq.XAttribute]::new("newVersion", $asm.GetName().Version<#$fi.VersionInfo.FileVersion#>))
    
        return [System.Xml.Linq.XElement]::new($ns1 + "dependentAssembly", $assemblyIdentity, $bindingRedirect)
    }
    function UpdateBindings([string] $webConfigPath, [string] $packageConfigPath, [string] $binPath) {
    
        $webConfig = [System.Xml.Linq.XDocument]::Load($webConfigPath)
        ClearBindings $webConfig
    
        [System.Xml.Linq.XDocument] $packageConfig = [System.Xml.Linq.XDocument]::Load($packageConfigPath)
        $packages = GetPackageList $packageConfig $binPath
    
        [System.Xml.Linq.XElement]$assemblyBinding = $webConfig.Root.Element("runtime").Element($ns1 + "assemblyBinding")
    
        $packages | ForEach-Object {
    
            [System.IO.FileInfo]$fi = [System.IO.FileInfo]::new($_)
            if ($fi.Exists) {
                $newElement = CreateBindingElement $fi
                $assemblyBinding.Add($newElement)
            }
        }
    
        $webConfig.Save($webConfigPath)
    }
    function LoadWindowsFormsAssembly() {
        if (!$isWindowsFormsAssemblyLoaded) {
            [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
            $isWindowsFormsAssemblyLoaded = $true
        }
    }
    function PromptForFile ([string]$title, [string]$filter) {
    
        LoadWindowsFormsAssembly
        [System.Windows.Forms.OpenFileDialog]$dialog = New-Object System.Windows.Forms.OpenFileDialog
        $dialog.Multiselect = $false
        $dialog.Title = $title
        $dialog.Filter = $filter
    
        if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { return $dialog.FileName }
        else { return $null }
    }
    function PromptForDirectory ([string]$title) {
    
        LoadWindowsFormsAssembly
        [System.Windows.Forms.FolderBrowserDialog]$dialog = New-Object System.Windows.Forms.FolderBrowserDialog
    
        if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { return $dialog.SelectedPath }
        else { return $null }
    }
    function MessageBox([string]$title) {
    
        LoadWindowsFormsAssembly
        [System.Windows.Forms.MessageBox]::Show($title)
    }
    
    if ([System.String]::IsNullOrEmpty($webConfigPath)) {
        $webConfigPath = PromptForFile 'Please select the web.config file' '.NET Configuration File (web.config)|web.config'
        if ([System.String]::IsNullOrEmpty($webConfigPath)) {exit}
    }
    
    if ([System.String]::IsNullOrEmpty($packagesConfigPath)) {
        $packagesConfigPath = PromptForFile 'Please select the packages.config file' 'NuGet Package  File (packages.config)|packages.config'
        if ([System.String]::IsNullOrEmpty($packagesConfigPath)) {exit}
    }
    
    if ([System.String]::IsNullOrEmpty($binPath)) {
        $binPath = PromptForDirectory "Please select your application's BIN directory"
        if ([System.String]::IsNullOrEmpty($binPath)) {exit}
    }
    
    
    UpdateBindings $webConfigPath $packagesConfigPath $binPath
    
    0 讨论(0)
提交回复
热议问题