Ответ 1
RID используются с .NET Core для разрешения зависимостей пакетов. Корнем для этого процесса разрешения зависимостей является ваш проект, который вы явно указываете на один или несколько RID. При создании проекта вы указываете, с каким RID вы строите против.
RID определены в лесу деревьев совместимости, где любой node в дереве представляет среду выполнения, которая может поддерживать все ее дочерние элементы. Каждый RID является корнем такого дерева.
Вот пример дерева совместимости RID:
win10-x64
|- win10
| `- win81
| `- win8
| `- win7
| `- win
| `- any
| `- base
`- win81-x64
|- win81 (already included above)
`- win8-x64
|- win8 (already included above)
`- win7-x64
|- win7 (already included above)
`- win-x64
`- win (already included above)
Здесь определен полный график деревьев совместимости RID:
https://github.com/dotnet/corefx/blob/master/pkg/Microsoft.NETCore.Platforms/runtime.json
В случае необходимости пакет может предоставить различную реализацию для каждого RID. При построении, если у меня есть зависимость от этого пакета, процесс сборки будет выбирать реализацию, ближайшую к корню дерева. Если дерево не содержит никаких RID, поставляемых пакетом, то сборка завершится с ошибкой.
Существует специальный вид пакета, называемый "пакет времени выполнения". Пакеты исполнения содержат собственные двоичные файлы, которые непосредственно загружаются и выполняются операционной системой хоста. Таким образом, эти пакеты предоставляют только версии для конкретных версий ОС: "win7-x64", например, но не "win7" или "win-x64", и, скажем, "ubuntu.16.04-x64", но не "ubuntu.16.04", "ubuntu-x64" или "linux".
[ Обновление: с .NET Core 2.0, вы можете построить для Linux-x64 для "всех" x64-версий Linux с помощью единой сборки. См. https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/]
Пакеты времени выполнения вступают в игру при объединении автономных проектов. При автономном проекте все необходимое для запуска проекта должно быть включено в вывод сборки. Это означает, что вывод сборки должен включать в себя двоичный файл native как точку входа для приложения. Этот встроенный двоичный файл предоставляется пакетом времени выполнения.
Итак, чтобы ответить на ваши вопросы:
- Если я укажу RID для win7-x32, мой код также будет запущен на 64-битной ОС Windows?
Да, будет, но он будет работать в 32-битном процессе. Я проверил это с помощью приложения, созданного и опубликованного с помощью Ubuntu dev VM, а затем запускается на Windows 10 64-bit; если приложение опубликовано с помощью win7-x32
, то IntPtr.Size
равно 4, и если оно опубликовано против win7-x64
, то IntPtr.Size
равно 8. Он работает в любом случае.
Пакет win7-x32
runtime включает 32-битный EXE файл, на котором размещается среда выполнения .NET Core, а затем загружает и запускает ваш проект, который связан вместе с ним в DLL файле с тем же именем.
- Если я укажу RID для win7, что он построит, построит ли он 32-битную версию или 64-битную версию?
Если вы укажете RID в win7
, он попытается найти собственные бинарные сборки, помеченные этим RID или совместимым RID, но он не найдет. Сборка не удастся, потому что нет версии win7 в главной точке входа EXE. Вы должны указать либо 32-разрядную, либо 64-разрядную (и похоже, что все остальные платформы имеют только 64-разрядные версии).
Я проверил эту конкретную деталь и обнаружил, что:
-
Шаг
dotnet restore
не прерывается, но также не устанавливает время выполнения дляwin7
(илиwin10
). -
Шаг
dotnet build
преуспевает в компиляции тестового приложения, но затем испускает эту ошибку:Не удалось выполнить следующий запуск проекта: helloworld (.NETCoreApp, Version = v1.1) Причина: ожидаемая библиотека coreclr не найдена в графе пакетов. Повторите попытку восстановления dotnet снова.
- Если я укажу RID для win7, будет ли моя программа работать в Windows 8, 8.1 или 10?
Предполагая, что вы указываете либо win7-x86
, либо win7-x64
, тогда да. В пакете времени win7-x86
или win7-x64
будет поставляться точка входа EXE, которая представляет собой 32-разрядную или 64-разрядную версию EXE, соответственно, и эти EXE являются исходными двоичными файлами, которые будут запускаться в любой версии Windows, начиная с Windows 7.
Обратите внимание, что в настоящее время нет пакета времени выполнения для Windows 8, Windows 8.1 или Windows 10. Графики совместимости для новых версий Windows включают в себя как win7-x86
или win7-x64
, в зависимости от ситуации, и поэтому конкретный пакет времени выполнения используется в сборке, даже если вы нацеливаете новый RID, такой как win10-x64
.
- Что делает любой МПОГ? Я понимаю, как переносное развертывание можно использовать на нескольких платформах, но как автономное развертывание (построенное с помощью RID любого) работает как с Linux, так и с Windows? Я не понимаю этого МПОГ?
RID any
позволяет пакету предоставлять реализацию для любого RID дальше по цепочке, потому что все другие RID в конечном итоге включают any
(и base
) в их дереве совместимости. Однако пакеты Runtime не предоставляют никакой реализации для any
, и поэтому any
не может использоваться для создания автономных пакетов.
- Если я укажу RID of blah, я ожидал ошибку. Вместо этого мое приложение было создано в каталоге bin/Release/blah. Это просто по умолчанию для какой-либо другой среды выполнения?
Ваш проект должен быть настроен с "type": "platform"
в зависимости от Microsoft.NETCore.App
. Таким образом, автономный пакет не был создан, а разрешение поддерживающих библиотек осталось на время выполнения, после чего RID будет предоставлен фактической средой выполнения, которую вы используете для запуска приложения, а не конфигурацией сборки приложения.
Если ваш проект является библиотекой, то при попытке ссылаться на него из другого проекта вы можете столкнуться с проблемами, потому что ваша библиотека только реализует реализацию для платформы "бла", которая не будет находиться в дереве совместимости для RID, против которого выступает другой проект. Если ваш проект является приложением, то blah
игнорируется.
Если вы перенастроете свой проект на создание автономного пакета (удалив или закомментировав строку "type": "platform"
в project.json
), вы обнаружите, что он больше не строит, поскольку теперь он имеет зависимость от времени выполнения пакетов, и нет пакета для RID blah
.