Как запустить Windows-программу на Linux: мой опыт с .NET
Недавно я столкнулся с интересной задачей — мне необходимо было построить программу, портированную с Windows на Linux. Источник кода был доступен на GitHub, а сама программа была написана на C#. Этот опыт стал для меня настоящей практикой в мире кросс-платформенной разработки.
Установка необходимых пакетов
Для успешной сборки программы мне потребовались определённые пакеты. Я установил dotnet-runtime
и dotnet-sdk
, а также несколько других, включая mono
и mono-msbuild
. Все необходимые файлы были помещены в каталог /opt
.
После сборки программы я обратил внимание на структуру установленных файлов. В каталоге /usr/local/bin/
обнаружилась ссылка на скрипт оболочки, который указывал на исполняемый файл программы в /opt/program/bin/
.
Запуск исполняемого файла
Скрипт оболочки вызывал команду для запуска исполняемого файла:
exec bin/Program.exe
Это вызвало у меня недоумение, так как я ожидал, что для запуска исполняемого файла Windows на Linux потребуется специальная программа-обертка, как это происходит с Java или Wine.
Однако, я был удивлён, когда смог запустить программу напрямую с помощью команды:
$ /opt/program/bin/Program.exe
Для уверенности я проверил файл с помощью команды:
$ file /opt/program/bin/Program.exe
Результат подтвердил моё предположение: это был исполняемый файл MS Windows.
Механизм выполнения Windows-программ на Linux
Я заинтересовался, как Linux смог запустить этот исполняемый файл, и вскоре нашёл ответ в механизме binfmt_misc
. Этот механизм позволяет ядру обрабатывать исполняемые файлы, которые не являются стандартными для используемой ОС. В частности, он включает поддержку файлов, начинающихся с #!/path/to/interpreter
.
Механизм настроен через интерфейс, расположенный в /proc/sys/fs/binfmt_misc
, а конфигурационные файлы можно найти в каталоге /etc/binfmt.d
, который читает служба systemd-binfmt.service
.
Я проверил свой каталог /etc/binfmt.d
, и, к своему удивлению, он оказался пустым. Тем не менее, информация в /proc/sys/fs/binfmt_misc/
была весьма информативной:
$ ls /proc/sys/fs/binfmt_misc/
CLR register status
$ cat /proc/sys/fs/binfmt_misc/CLR
enabled
interpreter /usr/bin/mono
flags:
offset 0
magic 4d5a
Это указывало на то, что "CLR" включен и для "интерпретатора /usr/bin/mono", идентифицированного "магией" 4d5a — что, как я позже выяснил, соответствует заголовку "MZ" для исполняемых файлов Windows.
Заключение
Установка пакетов, таких как dotnet-runtime
, задействует механизм, который облегчает запуск Windows-исполняемых файлов в Linux. Хотя процесс не всегда очевиден, по мере работы с платформами становятся ясны взаимодействия компонентов, позволяющие эффективно использовать любой софт независимо от операционной системы.
Если вы хотите портировать Windows-программы на Linux, мой опыт может стать хорошим стартом для вашего путешествия в мир кросс-платформенной разработки.