Автоматическое извлечение собственных и управляемых библиотек DLL из пакета Nuget

это сводит меня с ума в течение нескольких месяцев, и я все еще не могу этого достичь. Мои управляемые библиотеки извлекаются из пакета Nuget, но не из местных.

у нас есть куча управляемых и собственных библиотек, предоставляемые другой компанией. У нас есть оба x86 и x64 версия их. Для того чтобы использовать их в ASP.NET основной проект я должен создать пакет Nuget.

моя архитектура-это:

  • an ASP.NET Керн библиотека классов, которую я изменил на target full .NET Framework. Этот проект ссылается на мой пакет Nuget
  • an ASP.NET основной веб-сайт также ориентирован на полную .NET Framework и ссылается на библиотеку классов

конечно, в конце мне нужно, чтобы мои собственные библиотеки были извлечены в соответствующую папку времени выполнения веб-сайта (например:binDebugnet461win7-x64).

на данный момент мое решение было:

  • чтобы поместить родные libs внутри build папка
  • создать targets файл, который копирует их в $(OutputPath) (который даже не папка runtime)
  • добавьте некоторые команды MsBuild в xproj моего веб-сайта, чтобы получить целевой файл в моем $(USERPROFILE).nugetpackages папка и выполнить его
  • скопировать вручную собственные библиотеки DLL теперь извлекаются в до runtime один

я попытался скопировать их непосредственно в папку выполнения, используя некоторую конфигурацию в project.json (I честно говоря, не помню всех вещей, которые я пробовал для этой части), но это всегда терпело неудачу. Также, хотя я указал SkipUnchangedFiles="true" в моем целевом файле это просто игнорируется, и мои DLL копируются в мою папку bin во время каждой сборки.

это тяжелый процесс только для достижения извлечения DLL, теперь я действительно хочу избавиться от всего, что MsBuild и получить гораздо более простое решение.

я знаю с более новыми версиями Nuget, теперь он способен извлекать их изначально без какой-либо помощи добавления пользовательских команд MsBuild. Как написано здесь, проекты C# даже не нуждаются в

далее, проекты C++ и JavaScript, которые могут потреблять ваш пакет NuGet, нуждаются в a .целевой файл для определения необходимых файлов сборки и winmd. (Проекты C# и Visual Basic делают это автоматически.)

я держал вкладку, открытую в моем браузере в течение нескольких месяцев (ссылка на источник) и реализовать это ресурс был недавно удален с сайта Nuget. Он объяснял, как использовать runtimes папка для автоматического извлечения библиотеки DLL. Однако я никогда не мог получить успешный результат, как это было объяснено. Теперь эта страница была удалена и заменена этот с таким количеством объяснений и не говорить об этом runtimes папка вообще.

я предполагаю, что я должен использовать runtimes папка для собственных библиотек DLL и lib один для управляемого, но я не 100% уверен. (также я должен использовать ?)

я пробовал несколько вещей (я не могу вспомнить количество попыток, как я сказал несколько месяцев головной боли...) как эта архитектура (я не понимаю в чем смысл build/native а также папки аборигенов под runtimes) enter image description here

я также попытался использовать структуру версий .NET framework, как описано здесь для моей управляемой библиотеки.

этой кажется, также является частью решения

архитектура игнорируется компилятором при создании ссылки на сборку. Это концепция времени загрузки. Загрузчик предпочтет конкретную ссылку на архитектуру, если она существует.

один трюк, который вы можете использовать для создания сборки AnyCPU, - использовать corflags для удаления архитектуры из сборки x86. Например: corflags / 32BITREQ-MySDK.файл DLL. Corflags является частью .NET SDK и можно найти в командной строке разработчика VS.

вот что я сделал, конвертируя библиотеки x86 и x64 в AnyCPU (не знаю, делает ли он что-то для x64 DLL, но я не получил ошибок), а затем попробовал несколько разных архитектур в моем пакете Nuget, но все еще не работает.

среда выполнения по умолчанию без записи в project.json is win7-x64, поэтому я решил явно указать его на всякий случай

"runtimes": {
    "win7-x64": {}
},

так это идентификатор среды выполнения, который я использую для всех моих попыток в моем пакете Nuget. Однако меня не волнует версия windows. Я бы предпочел иметь win-x86 или win-x64, но, похоже, это недопустимое значение в соответствии с на этой странице

Windows RIDs

Windows 7 / Windows Server 2008 R2

  • С Win7-х64
  • С Win7-x86 в

Windows 8 / Windows Server 2012

  • на Win8-x64 не
  • на Win8-x86 в
  • win8-arm

Windows 8.1 / Windows Server 2012 R2

  • win81-x64
  • win81-x86
  • win81-arm

Windows 10 / Windows Server 2016

  • win10-64-разрядных
  • win10-x86
  • win10-arm
  • win10-arm64
этой источник Github описывает больше RID, так какой источник прав?

как вы можете видеть, есть так много тайн, в основном из-за отсутствия документов или противоречия между разными документами.

если бы у меня был хотя бы рабочий пример, я мог бы выполнить свои тесты, чтобы ответить на другие вопросы, такие как попытка generic win-x64 RID или посмотреть, могу ли я включить один раз мои управляемые библиотеки Версия .NET Framework.

Пожалуйста, обратите внимание на мой особый контекст:у меня есть ASP.NET основной проект, ориентированный на полную .NET Framework

Спасибо за ваши ответы, я отчаянно хочу, чтобы эта простая вещь работала.

1 ответов


я попытаюсь объяснить всю боль и решения, через которые я прошел, как можно подробнее. В моем примере я использую простые текстовые файлы AAA86.txt, AAA64.txt и AAAany.txt вместо собственных DLL, чтобы просто продемонстрировать процесс извлечения.

Первое, что вам нужно знать: Если вы попытаетесь смешать native архитектура NuGet с lib папка, содержащая некоторые управляемые библиотеки,ЭТО НЕ БУДЕТ Работа

enter image description here

в этом случае ваши управляемые библиотеки DLL будут скопированы в выходной каталог вашего проекта, но не ваши собственные.

спасибо Джону скиту, который указал мне в хорошем направлении, посоветовав взглянуть на Grpc.Основной пакет. Фокус в том, чтобы создать targets файл, который будет обрабатывать извлечение DLL.

enter image description here

ваш файл targets должен содержать что-то вроде этого

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup Condition=" '$(Platform)' == 'x64' ">
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\AAA64.txt">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>AAA64.txt</Link>
        </Content>
    </ItemGroup>

    <ItemGroup Condition=" '$(Platform)' == 'x86' OR '$(Platform)' == 'AnyCPU' ">
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\native\AAA86.txt">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>AAA86.txt</Link>
        </Content>
    </ItemGroup>

</Project>

теперь несколько других вещей, которые вы должны знать:

1) Visual Studio не важно вообще о настройках, которые вы выбираете, он всегда будет использовать фиктивный RID. (В моем случае я всегда заканчиваю с win7-x64 папка, хотя я нахожусь в Windows 10...)

enter image description here

2) на

{
    "buildOptions": {
        "platform": "x64"
    }
}

3) на настройки среды исполнения если вы устанавливаете только win и/или win-x64

"runtimes": {
    "win": {},
    "win-x64": {}
}

Visual Studio вместо этого будет использовать win7-x64. Но если добавить win10-x64 пока вы находитесь на машине Windows 10, это будет использоваться

4) если вы компилируете свое приложение с помощью универсального RID, как это

dotnet build -c debug -r win

затем ваш targets файл получит архитектуру ваша машина (x64 в моем случае) вместо AnyCPU как я и ожидал

5) если у вас есть только собственные библиотеки без какого-либо управляемого, то извлечение будет работать без целевого файла, если вы будете следовать архитектуре runtimes/RID/native

6) С только родными библиотеками в моем пакете, выбранное RID всегда будет win-x64 построение с Visual Studio, как я уже говорил, папка среды выполнения всегда создается win7-x64, независимо от конфигурации Я выбираю. Если бы у меня был хоть один!--12--> удалить в мой пакет, то он будет successufully ковыряться.