Как мне создать или загрузить 32-битный и 64-битный пакет NuGet? - PullRequest
38 голосов
/ 14 октября 2011

У меня есть бинарная версия для x86 и x64, которую я хочу загрузить в NuGet. Какая рекомендация или требуемый метод для создания / загрузки этого пакета? Я не могу найти много , чтобы обосновать свое решение. Я вижу два метода ...

  1. Загрузите их обоих в одном пакете
    • Какой из них установить по умолчанию?
    • Есть ли способ проверить архитектуру процессора проекта, чтобы принять решение?
  2. Загрузить два отдельных пакета

Бонусный вопрос: что, если я использую что-то вроде Chocolatey , которое объединяет NuGet с семантикой менеджера пакетов? Возможно, мне понадобятся / понадобятся пакеты x86 и x64, установленные в моей системе.

Ответы [ 3 ]

14 голосов
/ 07 июля 2012

Вы можете добавить поддержку x64 и x86 в проект, используя условные ссылки.Похоже, что сейчас Nuget не нравится иметь две ссылки с одинаковыми именами.Поэтому нам нужно добавить вторую ссылку вручную, а затем сделать ссылки условными.

Сохранить сборки x64 в папке с именами сборок x64 и x86 в папке с именем x86. Обе они должны иметь одинаковое имя сборки.Затем добавьте в массив allowReferences имена всех сборок, которые нужно добавить.

Используйте следующие сценарии.

Install.ps1

$allowedReferences = @("Noesis.Javascript")

# Full assembly name is required
Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

$projectCollection = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection

$allProjects = $projectCollection.GetLoadedProjects($project.Object.Project.FullName).GetEnumerator();

if($allProjects.MoveNext())
{
    $currentProject = $allProjects.Current

    foreach($Reference in $currentProject.GetItems('Reference') | ? {$allowedReferences -contains $_.Xml.Include })
    {
        $hintPath = $Reference.GetMetadataValue("HintPath")

        write-host "Matched againt $hintPath"

        #If it is x64 specific add condition (Include 'Any Cpu' as x64)
        if ($hintPath -match '.*\\(amd64|x64)\\.*\.dll$')
        {
            $Reference.Xml.Condition = "'TargetPlatform' != 'x86'"

            $condition = $Reference.Xml.Condition
            write-host "hintPath = $hintPath"
            write-host "condition = $condition"

            #Visual Studio doesnt allow the same reference twice (so try add friends)
            $matchingReferences = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -match ".*\\(x86)\\.*\.dll$")}

            if (($matchingReferences | Measure-Object).Count -eq 0)
            {
                $x86 = $hintPath -replace '(.*\\)(amd64|x64)(\\.*\.dll)$', '$1x86$3'
                $x86Path = Join-Path $installPath $x86

                if (Test-Path $x86Path) {
                    #Add 
                    write-host "Adding reference to $x86"

                    $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
                    $metaData.Add("HintPath", $x86)
                    $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)

                    $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $x86)} | Select-Object -First 1

                    $newReference.Xml.Condition = "'TargetPlatform' == 'x86'"           
                }
            }
        }

        #If it is x86 specific add condition 
        if ($hintPath -match '.*\\x86\\.*\.dll$')
        {
            $Reference.Xml.Condition = "'TargetPlatform' == 'x86'"

            $condition = $Reference.Xml.Condition
            write-host "hintPath = $hintPath"
            write-host "condition = $condition"

            #Visual Studio doesnt allow the same reference twice (so try add friends)
            $matchingReferences = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -match ".*\\(amd64|x64)\\.*\.dll$")}

            if (($matchingReferences | Measure-Object).Count -eq 0)
            {
                $x64 = $hintPath -replace '(.*\\)(x86)(\\.*\.dll)$', '$1x64$3'
                $x64Path = Join-Path $installPath $x64

                if (Test-Path $x64Path) {
                    #Add 
                    write-host "Adding reference to $x64"

                    $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
                    $metaData.Add("HintPath", $x64)
                    $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)

                    $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $x64)} | Select-Object -First 1

                    $newReference.Xml.Condition = "'TargetPlatform' != 'x86'"           
                } else {
                    $amd64 = $hintPath -replace '(.*\\)(x86)(\\.*\.dll)$', '$1amd64$3'
                    $amd64Path = Join-Path $installPath $amd64

                    if (Test-Path $amd64Path) {
                        #Add 
                        write-host "Adding reference to $amd64"

                        $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
                        $metaData.Add("HintPath", $amd64)
                        $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)

                        $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $amd64)} | Select-Object -First 1

                        $newReference.Xml.Condition = "'TargetPlatform' != 'x86'"           
                    }               
                }               
            }           
        }
    }
}

Uninstall.ps1

$allowedReferences = @("Noesis.Javascript")

# Full assembly name is required
Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

$projectCollection = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection

$allProjects = $projectCollection.GetLoadedProjects($project.Object.Project.FullName).GetEnumerator();

if($allProjects.MoveNext())
{
    foreach($Reference in $allProjects.Current.GetItems('Reference') | ? {$allowedReferences -contains $_.UnevaluatedInclude })
    {
        $allProjects.Current.RemoveItem($Reference)
    }
}
12 голосов
/ 22 ноября 2011

Мы обсуждали аналогичную проблему в Chocolatey Google Group . В NuGet нет встроенной семантики. Не будет требоваться какая архитектура процессора у вас установлена ​​на . Это должно быть на какую архитектуру процессора нацелен ваш проект. И тогда это усложнит вещи ... вам также придется понять AnyCPU.

Я думаю, сейчас я собираюсь загрузить два пакета. Я всегда могу опубликовать комбинированный, когда исправляю install.ps1, который может обрабатывать запросы к цели проекта.

mypackage.x86
mypackage.x64
0 голосов
/ 14 октября 2011

Кажется, что нет конкретной цели для 32- или 64-битных архитектур.Немного неприятно, но можете ли вы что-то сделать с помощью сценариев PowerShell (install.ps1), чтобы определить архитектуру и установить ее соответствующим образом?

См. Автоматически запускаемые сценарии PowerShell во время установки и удаления пакета - http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package

...