Как запустить программу для windows на линуксе

Поскольку вы находитесь здесь, я предположу, что вы пользователь Linux. И время от времени вы задаетесь вопросом: могу ли я запускать приложения windows в Linux?

Ответ на этот вопрос — да, вы можете запускать приложения Windows в Linux. Вот некоторые способы запуска программ Windows в Linux:

  • Установка Windows на отдельный раздел жесткого диска
  • Установка Windows в качестве виртуальной машины в Linux

Оба они работают просто отлично. Но они несколько требовательны к ресурсам.

Если вам нужно использовать только небольшое приложение Windows, установка Windows на отдельный раздел жесткого диска или в качестве виртуальной машины неэффективна. Более того, виртуальная машина не может использовать всю мощность вашей машины. Итак, каково же решение?

Не волнуйтесь, есть другой способ использовать программное обеспечение Windows в Linux. Он называется Wine. Если вы еще не знакомы с ним или являетесь новичком в мире Linux, эта статья для вас.

В этом руководстве для начинающих я покажу вам, что такое Wine и как использовать его для запуска программ Windows в Linux. Я использовал здесь Ubuntu, поскольку Ubuntu является одним из лучших дистрибутивов Linux для начинающих, но любой другой дистрибутив Linux будет иметь более или менее те же шаги (за исключением команд в дистрибутивах на базе Arch или Fedora).

Wine означает Wine Is Not an Emulator. И WINE на самом деле является акронимом этого слова. И, как уже говорилось ранее, это даже не виртуальная машина.

Скорее это уровень совместимости для запуска приложений Windows на UNIX-подобных или POSIX-совместимых операционных системах (например, Linux, Mac, BSD). В то время как виртуальная машина или эмулятор имитирует внутреннюю логику Windows, Wine переводит эту логику Windows в родную логику UNIX/POSIX-совместимости.

Говоря простыми и нетехническими терминами, Wine преобразует внутренние команды Windows в команды, которые ваша Linux-система может понимать как родные.

Установка Wine

Существуют различные способы установки Wine на вашу систему. Поскольку это руководство для начинающих, я опишу самый простой из них.

Почти все дистрибутивы Linux поставляются с Wine в репозитории пакетов. Чаще всего в репозитории пакетов доступна последняя стабильная версия Wine. Установить Wine на Ubuntu так же просто, как открыть терминал и выполнить следующие команды:

sudo apt update
sudo apt install wine

Однако если вы используете 64-разрядную установку Ubuntu, вам потребуется выполнить эти дополнительные команды:

sudo dpkg --add-architecture i386

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

Какие приложения Windows поддерживаются Wine?

Существует большое количество приложений Windows, которые в настоящее время полностью поддерживаются Wine. Они будут работать без каких-либо проблем.

Однако каждый день разрабатываются новые приложения Windows. Многие из них не будут работать в Wine так, как мы хотим. Но темпы развития Wine также стремительны, поддержка новых приложений добавляется постоянно.

И для отслеживания этого существует специальная база данных.

База данных приложений Wine содержит почти 24 000 приложений, имеющих различные статусы в зависимости от того, насколько хорошо эти приложения работают в Wine. Если вы хотите быстро проверить рейтинг приложения, которое вы хотите использовать в Wine, вы можете заглянуть туда. Вот значение этих рейтингов:

  • Platinum: Эти приложения устанавливаются и безупречно работают в «готовом» Wine.
  • Gold: Эти приложения работают безупречно с некоторыми специальными настройками.
  • Silver: Приложения с незначительными проблемами помечаются как Silver.
  • Bronze: Бронзовые имеют серьезные проблемы, которые достаточно сильно влияют на использование.
  • Garbage: Они просто не будут работать в Wine.

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

Разумеется, база данных приложений Wine — это в основном пользовательские данные, поэтому вы всегда можете попробовать запустить приложение с другой версией Wine и поделиться своими результатами с остальными членами сообщества.

Поиск приложения в базе данных приложений Wine

Давайте посмотрим, как мы можем найти приложение в базе данных приложений Wine.

Перейдите в раздел База данных приложений Wine. Нажмите кнопку Browse Apps (Обзор приложений) на левой боковой панели.

Finding an App in Wine AppDB

Поиск приложения в Wine AppDB

Напишите имя приложения, которое вы хотите найти, в поле Имя.

Wine AppDB name filter

Фильтр имен Wine AppDB

Нажмите на ссылку-приложение из результата поиска.

Вы увидите описание приложения. Там будет список различных версий с рейтингом их совместимости с конкретной версией Wine.

Wine AppDB Application page

Страница приложения Wine AppDB

Давайте нажмем на ссылку «Последняя версия».

Это главная страница, которую вам нужно проверить. Там будет подробная информация об этой конкретной версии.

Detailed Information about Application

Подробная информация о приложении

Вы получите представление о том, что будет работать, а что нет. Также здесь будет приведена процедура установки, если для установки потребуются какие-либо дополнительные задачи.

Начало работы с Wine

Прежде чем приступить к установке и запуску приложений в Wine, мы должны иметь четкое представление о некоторых вещах и о том, как настроить Wine для использования:

WinePrefix

Приложениям Windows необходим диск C:. Wine использует для этой цели виртуальный диск C:. Каталог этого виртуального диска C: называется wineprefix. Прежде всего, нам нужно создать wineprefix. Для этого откройте терминал и введите следующую команду:

winecfg

Это создаст wineprefix и откроет окно конфигурации для Wine. Вы можете изменить параметры конфигурации, если хотите, или оставить все как есть и закрыть его. Теперь вы можете найти виртуальный диск C: по адресу

$HOME/.wine/c_drive

WinePrefix C: Drive

WinePrefix C: Диск

Общее правило — устанавливать каждое новое приложение в новый wineprefix. Мы можем создавать и поддерживать несколько wineprefix вручную. Но эта задача покажется довольно утомительной для новичков. Поэтому мы пока пропустим эту часть. Но позже я покажу, как можно легко выполнить эту часть.

Установка приложения с помощью Wine

Установка поддерживаемого приложения в Wine обычно не сложнее двойного щелчка по установочному файлу. Однако сейчас мы рассмотрим пошаговое руководство по установке 7-zip в Wine.

Прежде всего, проверьте рейтинг 7-zip в базе данных приложений Wine. Он имеет рейтинг Platinum, так что все готово. Откройте конфигурацию Wine ( winecfg ) и установите версию Windows на Windows 7.

Wine Windows 7

Wine Windows 7

Щелкните правой кнопкой мыши на установочном файле 7-zip и выберите Open With Wine Windows Program Loader.

7-zip Installation File

Установочный файл 7-zip

Видите путь к конечной папке? Установка 7-zip распознала виртуальный диск C: из wineprefix.

7zip Setup Directory on Wine

7-zip Установочный каталог в Wine

Завершите установку и перейдите в каталог установки [ $HOME/.wine/drive_c/Program Files/7-zip/ ] из браузера файлов.

Щелкните правой кнопкой мыши на файле 7zFM.exe и выберите Свойства > Открыть с помощью.

Set Default .exe Loader

Установка загрузчика .exe по умолчанию

Выберите Wine Windows Program Loader и закройте окно. Дважды щелкните на файле 7zFM.exe.

7-zip running with Wine

7-zip работает в Wine

И вот, пожалуйста! Для создания ярлыка на рабочем столе щелкните правой кнопкой мыши на файле.

Creating 7-zip shortcut

Создание ярлыка 7-zip

Теперь переместите ссылку на рабочий стол.

Move shortcut to Desktop

Переместить ярлык на рабочий стол

Теперь вы можете запускать 7-zip просто с рабочего стола. Все, что вам нужно сделать, это дважды щелкнуть по значку.

Run 7zip from desktop

Запустите 7-zip с рабочего стола

Если вы хотите получить доступ к своим файлам в Linux, они обычно находятся на диске Z:.

Linux directory in Z: drive

Каталог Linux на диске Z:

Вы можете использовать 7-zip так же, как и в Windows — для извлечения и создания архивов и тому подобного.

Давайте сделаем все (намного) проще

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

Это связано с быстрыми темпами развития Wine. Хотя приложение работает с текущей версией Wine, оно может не работать с будущей версией из-за внесенных изменений.

Кроме того, я упоминал об установке каждого приложения в свой собственный свежий wineprefix. Таким образом, у приложения нет шансов помешать другому. И делать все это вручную, как правило, из терминала, отнимает много времени, утомляет и порой сбивает с толку.

На помощь приходит PlayOnLinux. Он предоставляет удобный интерфейс для выполнения всех этих действий. Для установки PlayOnLinux на Ubuntu просто выполните эту команду:

sudo apt install playonlinux

PlayOnLinux interface

Интерфейс PlayOnLinux

С помощью PlayOnLinux вы можете легко выполнить любую задачу, связанную с Wine, используя красивый и интуитивно понятный графический интерфейс:

  • Установка и удаление приложений.
  • Создание, обновление и удаление wineprefixes.
  • Поддерживать Wine различных архитектур и версий.
  • Запуск и создание ярлыков для установленных приложений.
  • И так далее…

Но все же вам нужно будет проверить базу данных приложений Wine на предмет отзывов, процедур установки и тому подобного.

Преимущества использования Wine

Когда речь идет о запуске приложений Windows в системе Linux, Wine предоставляет множество преимуществ по сравнению с использованием эмуляторов или виртуальных машин.

  • Производительность: Wine не подвержен снижению производительности, которое в противном случае происходит при эмуляции.
  • Нативный опыт: Нет необходимости открывать Wine перед запуском приложения Windows. Как именно работает Wine, станет более понятно из этой цитаты с официального сайта,

Wine можно рассматривать как эмулятор Windows примерно так же, как Windows Vista можно рассматривать как эмулятор Windows XP: оба позволяют запускать одни и те же приложения, переводя системные вызовы примерно одинаковым образом. Настройка Wine для имитации Windows XP мало чем отличается от настройки Vista для запуска приложения в режиме совместимости с XP.

Производные Wine

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

  • CrossOver: CrossOver разработан компанией CodeWeavers. Она основана непосредственно на Wine с некоторыми изменениями и собственными дополнениями. На самом деле, в CodeWeavers работает большая часть разработчиков Wine. В отличие от быстрых релизов Wine, релизы CrossOver более стабильны. Единственным и основным недостатком является то, что Crossover не является бесплатным.
  • PlayOnLinux: PlayOnLinux полностью основан на Wine. Он обеспечивает более легкий путь для установки и управления приложениями с помощью Wine. PlayOnLinux бесплатен. Он также доступен для Mac как PlayOnMac.
  • ReactOS: ReactOS — это совершенно другая операционная система с открытым исходным кодом для запуска приложений Windows. В ней повторно используется значительное количество кода из Wine. Однако этот проект находится в разработке уже более десяти лет, и я не стал бы его рекомендовать.

Дополнительные советы по использованию Wine

Winetricks

Это еще одна важная часть использования Wine. Winetricks — это вспомогательный скрипт для загрузки и установки различных перераспределяемых библиотек времени выполнения, необходимых для запуска некоторых приложений в Wine. Они могут включать замену компонентов Wine, использующих библиотеки с закрытым исходным кодом. Winetricks поставляется вместе с установкой Wine на Ubuntu.

Для запуска winetricks выполните эту команду:

winetricks

Winetricks

Winetricks

Существует множество вариантов помощи в решении различных задач.

Установка приложения с помощью Winetricks

Если вы установите приложение из winetricks, оно будет установлено в отдельный wineprefix. Давайте установим VLC:

Winetricks - Install an app

Winetricks – Установить приложение
Winetricks - Install VLC
Winetricks – установить VLC

После этого начнется загрузка установочных файлов VLC. А затем проведет вас через весь остальной процесс. Это довольно просто.

Установка DLL или компонентов Windows и другое

Вы можете выбрать wineprefix из winetricks и установить различные библиотеки и компоненты, необходимые для запуска приложения, а также выполнить другие операции.

Winetricks Scripts

Сценарии Winetricks
Winetricks Libraries & Components
Библиотеки и компоненты Winetricks

Примечание: Если использование winetricks кажется вам сложным, это совершенно нормально. Я тоже так считаю. По этой причине я всегда использую PlayOnLinux. PlayOnLinux может делать все, что вам может понадобиться от winetricks.

Для получения дополнительной информации вы можете ознакомиться с FAQ и документацией по Wine.

Я надеюсь, что это руководство для начинающих по использованию Wine в Linux будет вам полезно. Теперь вы можете запускать программы Windows в Linux без установки виртуальной машины или двойной загрузки.

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

Если вы считаете, что GIMP не ровня Photoshop, и не можете жить без офиса от Microsoft.

5 способов установить Windows-программы на Linux

1. Wine

Название Wine расшифровывается как Wine Is Not an Emulator. Это своего рода прослойка между приложениями Windows и системой Linux. Он позволяет устанавливать и запускать многие популярные Windows-программы и работать с ними так, как будто это родные приложения Linux.

Чтобы установить Wine, воспользуйтесь соответствующей командой.

1. Ubuntu, Debian, Mint:

sudo dpkg --add-architecture i386

wget -nc https://dl.winehq.org/wine-builds/Release.key

sudo apt-key add Release.key

sudo add-apt-repository "deb https://dl.winehq.org/wine-builds/ubuntu/ artful main"

sudo apt-get update

sudo apt-get install --install-recommends winehq-stable

2. Fedora:

sudo dnf install winehq-stable

3. openSUSE:

sudo zypper install wine

4. Arch, Manjaro:

sudo pacman -S wine

Когда Wine установлен, откройте его через ваше меню приложений или с помощью команды winecfg. При первом запуске Wine может попросить установить некоторые дополнительные пакеты — позвольте ему это сделать. После этого все Windows-программы формата EXE ассоциируются в системе с Wine.

Теперь скачайте установщик нужного вам приложения Windows, найдите папку с ним в вашем файловом менеджере и откройте файл. Либо введите команду wine путь_к_приложению.

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

Не все приложения могут быть установлены и запущены в Wine, хотя количество поддерживаемых впечатляет. Полный список можно посмотреть здесь.

2. Winetricks

Wine — неплохой инструмент, однако интерфейс у него оставляет желать лучшего. Если вы намучились с этой программой, но так и не добились результата, попробуйте Winetricks. У неё приятный графический интерфейс для установки и запуска Windows-приложений, в котором куда проще разобраться новичку.

Установить Winetricks можно так:

1. Ubuntu, Debian, Mint:

sudo apt-get install winetricks

2. Fedora:

sudo dnf install winetricks

3. openSUSE:

sudo zypper install winetricks

4. Arch, Manjaro:

sudo pacman -S winetricks

Winetricks позволяет установить различные версии Microsoft Office и Photoshop, плеер foobar2000 и множество других программ. Поддерживаются и такие популярные игры, как Call of Duty, Call of Duty 4, Call of Duty 5, Biohazard и Grand Theft Auto: Vice City. Некоторые программы загружаются автоматически, для других будет предложено вставить установочный носитель. И, естественно, вы можете открывать собственноручно скачанные файлы формата EXE.

3. PlayOnLinux

PlayOnLinux — ещё один удобный инструмент для запуска Windows-приложений в Linux. Как и Winetricks, он обладает простым графическим интерфейсом. Но, в отличие от него, PlayOnLinux позволяет вам выбирать конкретную версию Wine для того или иного приложения. Это полезно, если какая-то из нужных вам программ некорректно работает с новыми версиями Wine. В целом PlayOnLinux выглядит куда симпатичнее и практичнее, чем Winetricks.

Чтобы установить PlayOnLinux, выполните в терминале одну из следующих команд:

1. Ubuntu, Debian, Mint:

sudo apt-get install playonlinux

2. Fedora:

sudo dnf install playonlinux

3. OpenSUSE:

sudo zypper install playonlinux

4. Arch, Manjaro:

sudo pacman -S playonlinux

В меню установки PlayOnLinux можно найти множество предварительно сконфигурированных приложений и игр, которые вы можете загрузить и установить парой щелчков. Кроме того, PlayOnLinux можно скармливать собственные EXE-установщики. Приложение заботливо выберет за вас версию Wine и создаст значок установленной программы на рабочем столе.

4. Crossover

Изредка бесплатные PlayOnLinux и Winetricks не справляются с установкой какого-нибудь особенно привередливого приложения. В таком случае вам может помочь Crossover. Эта программа очень проста в использовании. Вам достаточно указать, какое приложение вы хотите установить, и подсунуть Crossover установочный файл. Всё остальное будет сделано за вас.

Лицензия Crossover на год стоит 39,95 доллара, но у программы есть и бесплатная пробная версия. Рекомендуется сначала установить необходимое вам приложение в ней, чтобы убедиться, что оно работает корректно.

Crossover →

5. VirtualBox

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

Для запуска приложения в виртуалке вам понадобится установочный образ Windows в формате ISO. Загрузите и установите VirtualBox, создайте в нём виртуальную машину, укажите ей ISO с Windows, а затем просто установите систему как обычно.

Неоспоримый плюс виртуальной машины — в ней работает полноценная операционная система, а значит, запустится абсолютно всё. Минус — прожорливость в плане системных ресурсов, да и тратиться на лицензию Windows для виртуалки накладно.

VirtualBox →

Читайте также 🧐

  • 6 задач, с которыми Linux справляется лучше, чем Windows
  • Как реанимировать Windows и сохранить данные с помощью live-дистрибутива Linux
  • Как обмениваться файлами по воздуху между Windows, macOS, Linux, iOS и Android

Рано или поздно может понадобиться запустить программы Windows на Linux. Для операционной системы Linux написано огромное количество программ, для решения одной определенной задачи, может быть даже несколько десятков программ. Но такая тенденция наблюдается только для широко распространенных задач, что же касается специализированных программ и игр, то тут ситуация совсем иная.

Программ, для решения узкоспециализированных задач, например, в той же сфере СЕО для Linux попросту нет, а игры начали появляться только последние несколько лет. Были и раньше простенькие игры с открытым исходным кодом, но популярные игры, класса ААА начали появляться только тогда, когда этой платформой заинтересовалась Valve. Но до сих пор ситуация с играми обстоит не так, как хотелось бы. Поэтому и возникает необходимость установки Windows программ в Linux.

Немного теории

Windows программы не могут запускаться просто двойным щелчком по исполняемому файлу. Формат исполняемых файлов Linux очень сильно отличается от Windows. Поэтому для их запуска необходимо использовать специальное программное обеспечение — wine. Название Wine образовано с помощью, почему-то популярного в мире свободного программного обеспечения способа — рекурсивный акроним, и расшифровывается как Wine is not emultor. И это правда, wine не является эмулятором.

Это программная оболочка, которая преобразует системные вызовы Windows программ в вызовы функций операционной системы Linux. Таким образом, wine представляет из себя прослойку между Windows программой и операционной системой Linux вместе с ее ядром и библиотеками.

Чтобы понять как работает Wine, нужно сначала сказать несколько слов о ядре Windows. У Windows, так же как и у Linux есть ядро. Как вы знаете ядро Linux состоит из одного файла и находится в папке boot. Ядро Windows совсем другое, по сути это набор dll библиотек, которые расположены в папке C:\windows\system32. Поэтому нам, чтобы заставить Windows программы работать в Linux достаточно реализовать dll библиотеки, которые нужны программе, так чтобы они вызывали необходимые нам функции из системы linux, что собственно и делает Wine. Но проект развивается очень медленно и разработчики не успевают реализовать все функции из системных библиотек Windows, поэтому работают далеко не все программы, особенно новые.

Популярные программы в Wine запускаются легко, и без дополнительных настроек. Но дело в том, что для решения популярных и востребованных задач в Linux есть достаточно альтернатив, а запускать нам придется специализированные программы и игры, требующие серьезных компонентов, еще не написанных в Wine. Вот тут и всплывает недоработанность этой программы. Но есть выход, его мы и рассмотрим дальше.

Основы использования Wine

Все файлы программ wine, установленные программы, библиотеки, файлы реестра, конфигурационные файлы находятся в домашнем каталоге, а точнее, в ~/.wine.

Поскольку для разных программ, понадобится разная архитектура библиотек и нужно будет подменять на оригинальные библиотеки от windows разные файлы была придумана такая возможность, как префиксы.

Папка ~/.wine это префикс, но мы можем создавать для каждой новой программы свой префикс и она будет работать только с ним. Чтобы задать префикс, с которым нужно работать wine используется переменная окружения WINEPREFIX, например:

export WINEPREFIX=~/program

Для разных программ может потребоваться различная архитектура системы, wine может запускать и 64 битные программы, но многим для правильной работы нужна архитектура х86.

Чтобы задать архитектуру используйте переменную WINEARCH. Например, для х86:

export WINEARCH=win32

Также не создавайте папку для нового префикса с помощью mkdir или файлового менеджера, пусть программа сама создаст эту папку при своем первом запуске.

Прослойка совместимости Wine поддерживает далеко не все программы, чтобы проверить поддерживается ли программа Wine вы можете воспользоваться сайтом appdb.winehq.org здесь есть поиск и перечислены все поддерживаемые и не очень программы для Linux.

Запуск exe программ в Linux с помощью wine

Первым делом, надо посмотреть страницу программы на сайте appdb.winehq.com. Здесь есть поиск, поэтому вы можете попытаться искать нужную программу. Например, я хочу установить довольно популярную программу Notepad++. Cначала надо посмотреть поддерживается ли она Wine. Для этого на сайте есть поиск:

На странице программы есть версия Wine, с которой она была протестирована, версия тестируемой программы, а также оценка. Оценка может быть Platinum, Gold, Silver или ниже, она зависит от того насколько хорошо программа работает:

Как видите, программа тестировалась с версией wine 5.0 и работала довольно неплохо. К тому же на странице есть ссылка на загрузку программы, так как она бесплатна. Если при запуске программы возникают сложности, то на странице winehq обычно сообщается что надо сделать чтобы программу всё-таки запустить.

Если вам нужно запустить программу, полностью поддерживаемую Wine, например, проводник или notepad, достаточно выполнить:

$ wine /адрес/файла/программы.exe

Например, для программы Notepad++ надо выполнить:

wine ~/Загрузки/npp/notepad++.exe

Здесь я использую portable версию, её надо перед этим скачать и распаковать. Как видите, программа полностью работает:

Но как я уже говорил, нам придется запускать мало таких программ, большинство из них будут требовать функциональности, которая ещё не реализован в wine. Тогда нам придется заменить библиотеки Wine, на оригинальные библиотеки Windows.

Конечно, есть оболочки для Wine, которые автоматизируют этот процесс, например, Crossover, PlayOnLinux, Lutris и другие. Но мы рассмотрим ручной вариант.

Для установки компонентов Windows в wine существует специальный инструмент — winetricks. Устанавливать его лучше из сайта программы, так версия будет новее:

wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
chmod +x winetricks

Чтобы установить нужный компонент достаточно передать имя этого компонента:

$ winetricks имя_компонента

С установкой компонентов более-менее понятно, но как узнать какие компоненты нужны? Скорее всего, вашу программу уже пытались устанавливать и другие пользователи нашли решение проблемы. Поэтому воспользуйтесь поиском Google для того, чтобы найти способы установки программы. Также очень полезным будет сайт appdb.winehq.org.

Давайте рассмотрим пример. Наберите в поиске по appdb.winehq.com программу Internet Explorer 8, это последняя версия программы, которую можно установить в Linux. Как видите, здесь бронза, значит программа поддерживается:

На её странице сообщается, что программа работает, но для её работы надо установить компонент msxml и urlmon:

winetricks msxml6 urlmon

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

wine ~/Загрузки/iexplorer.exe

После установки вы можете её запустить:

Выглядит всё не очень, но зато работает. Инструкции не обязательно искать только на winehq, это могут быть различные форумы, блоги и так далее.

Остается вопрос, что же делать, если инструкций нет, информации минимум, а нужно чтобы программа работала. Мы можем анализировать вывод Wine при запуске программы. Причем нас будут интересовать не все сообщения из лога программы, а только последние, именно то что вызвало ошибку. Например если программа вывела:

fixme:richedit:ITextRange_fnEndOf (0xa04410)->(6 0 (nil)): stub
fixme:richedit:ITextRange_fnEndOf (0xa04410)->(6 0 (nil)): stub
fixme:richedit:ITextRange_fnEndOf (0xa04410)->(6 0 (nil)): stub

Осталось понять, что такое richedit, и Microsoft TechNet нам любезно сообщает что это их API и состоит оно из Riched32.dll, это последняя версия, но раньше это была riched20.dll, уже понимаете какие библиотеки нужны?

Их можно установить с помощью winetricks, но это делать необязательно, можно и вручную. Скачайте библиотеки, найти их не составит труда с помощью Google. Только ищите версию для Windows XP.

Копируем библиотеку в наш префикс, в папку system32:

cp ~/Загрузки/riched32.dll ~/program/drive_c/windows/system32/

cp ~/Загрузки/riched20.dll ~/program/drive_c/windows/system32/

Для 64 битных библиотек используется папка syswow64, а поскольку мы указали архитектуру 32 бит нужно и библиотеки использовать соответствующие. Затем запустите winecfg и на вкладке библиотеки, в поле новое замещение для библиотеки наберите *riched32, затем добавить и *riched20 и опять добавить:

Все, теперь можете пробовать запускать программу. Если программа снова падает с ошибкой, смотрите дальше логи и ищите библиотеки, которых ей не хватает.

Таким образом, вы можете заменить много библиотек Wine. Можно запустить практически любую программу, написанную несколько лет назад и не требующую сверх новых технологий. Достаточно только заменить нужные библиотеки. Вы можете не только использовать winetricks или копировать библиотеки из интернета, но и брать их прямо из Windows. Точно не стоит заменять gdi32.dll, kernel32.dll, и user32.dll — эти библиотеки реализуют функции ядра Windows на самом низком уровне, и если их заменить, это только нарушит работу Wine. Наверное, есть и другие библиотеки, которые нельзя заменять, но это вычисляется только путем экспериментов.

Вариант, который мы рассмотрели выше слишком сложный и не очень то подходит для новичков. Специально для таких ситуаций были придуманы различные программные решения вроде PlayOnLinux или CrossOver. Это оболочки над wine, которые уже знают какие библиотеки надо ставить для той или иной программы. Вы просто выбираете программу, выбираете установщик, а дальше программа сделает всё за вас сама.

Утилита Crossover поддерживает множество программ и работают они довольно неплохо, но единственный минус этой программы в том, что она платная. Программа PlayOnLinux бесплатная, но поддерживает намного меньше программ.

Запуск Windows программ в виртуальной машине

Если ни один из перечисленных выше способов вам не помог, осталось только последнее решение. Оно поможет, при условии, что у вас мощный компьютер. Вы можете установить виртуальную машину VirtualBox, затем установить туда Windows и уже там запускать вашу программу. Можно пойти ещё дальше и сделать из старого компьютера сервер, на котором будет запущена Windows, к которой вы сможете подключаться по VNC или RDP и делать там всё, что угодно. Это не совсем способы запуска exe в Linux, однако это решение будет работать почти всегда, где не будет работать wine.

Выводы

Теперь вы знаете как запустить exe на Linux. Не пренебрегайте инструментами упрощения установки вроде PlayOnLinux. Они очень сильно экономят ваше время, так как имеют уже готовые профили для многих программ. Экспериментируйте и пусть ваши программы работают без ошибок!

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Для операционных систем на базе Linux написано огромное количество программ. Несмотря на это, иногда возникает необходимость производить запуск Windows программ под Linux. В основном, это касается игр и некоторых специализированных программ, аналоги которых в Linux отсутствуют. Кроме того, некоторые пользователи, переходя с Windows на Linux, уже привыкли к определенному набору программного обеспечения и желают его использовать в дальнейшем. В этом случае предпочтительнее все же найти аналогичные программы для Linux и освоить их, поскольку в родной операционной системе программы работают обычно лучше и стабильнее. Поэтому рекомендуем запускать Windows программы под Linux только после того, как вы убедитесь, что аналогов нужных программ под Linux нет, или они вам не подходят.

Запустить программу, написанную для Windows в Linux, можно несколькими способами: с использованием Wine и продуктов на его основе, с помощью виртуальных машин и эмуляторов: VirtualBox, VMware, Parallels Workstation, QEMU. Теоретически еще есть возможность портирования программ с Windows на Linux при наличии исходного кода и навыков программирования, но этот вариант мы здесь рассматривать не будем.

Программы под Wine обычно работают быстрее, чем в виртуальных машинах. Это особенно актуально для современных 3D игр. Wine не требует установки операционной системы и позволяет быстро менять версию системы, библиотек и другие параметры. Запускать программы можно непосредственно в среде Linux. С другой стороны, для настройки Wine все равно придется потратить некоторое время и возможно неоднократно при запуске отдельных программ и игр. В виртуальных машинах запускаются оригинальные версии Windows и прочие операционные системы, которые нужно предварительно установить и настроить. Системе выделяются определенные ресурсы компьютера, эмулируется стандартное оборудование. Перед выполнением программы нужно предварительно запустить эмулятор и загрузить операционную систему, на что требуется дополнительное время. Следует отметить, что некоторые программы имеют защиту от запуска под виртуальными машинами.

Установка Wine

Мы рассмотрим установку Wine на Ubuntu и систем на ее базе (Linux Mint, Kubuntu и т.п.).Пользователи других операционных систем могут скачать Wine и прочитать инструкции по установке здесь: http://www.winehq.org/download/

Открываем терминал комбинацией клавиш Ctrl+Alt+T. Добавляем репозиторий с Wine командой:

sudo add-apt-repository ppa:ubuntu-wine/ppa

Вводим пароль администратора. В процессе установки нужно будет нажать клавишу «Enter».

Если вы будете производить апгрейд системы, например, обновлять Ubuntu 13.10 до Ubuntu 14.04, то придется повторить вышеуказанную операцию после апгрейда, поскольку в процессе обновления нестандартные репозитории удаляются.

После добавления репозитория обновляем информацию о пакетах:

sudo apt-get update

Теперь можно установить Wine командой:

sudo apt-get install wine1.7

Установится последняя, на момент написания статьи, тестовая версия программы. Для установки старой, но более стабильной версии нужно выполнить команду:

sudo apt-get install wine1.6

Возможно, когда вы будете читать эту статью, уже появятся более новые версии, тогда вместо wine1.6 или wine1.7, надо будет устанавливать wine1.8 или wine1.9. Номер текущей версии указан на официальном сайте Wine: http://www.winehq.org

Хотя можно и не указывать версию при установке, версия Wine в этом случае будет зависеть от версии операционной системы:

sudo apt-get install wine

Проверить, какая версия установилась, можно с помощью команды:

wine —version

Настройка Wine

После установки необходимо настроить программу командой:

winecfg

Рис. 1. Окно настроек winecfg

Это команда создаст в домашней директории пользователя каталог .wine, где будут находиться системные файлы с настройками — аналог реестра Windows и drive_c — каталог для приложений Windows. С помощью winecfg можно выбрать версии Windows по умолчанию и для отдельных приложений, версии библиотек, настроить графику и звук, интеграцию с рабочим столом, выбрать диски, с которых разрешен запуск Windows-программ.

А редактировать реестр можно с помощью привычной команды:

regedit

Рис. 2. Окно regedit под Wine

После такой первоначальной настройки, уже можно будет устанавливать и запускать программы с помощью Wine. Но многие программы работать не смогут, поскольку требуют определенных библиотек, шрифтов и т.д., которые придется установить отдельно. Для этого воспользуемся программой winetricks, которая входит в стандартный пакет программ Wine. Winetricks кроме шрифтов и библиотек позволяет также устанавливать популярные программы и игры и производить настройки Wine.

Попробуем установить Internet Explorer 7 с помощью winetricks, для этого наберем в терминале:

winetricks ie7

Подождем некоторое время, пока скачаются необходимые файлы и запустится программа-установщик, нажмем кнопку «Next» и подождем окончания установки. Для последующего запуска Internet Explorer нужно будет выполнить команду:

wine ‘C:\Program Files\Internet Explorer\iexplore’

Но лучше запускать программы из родного каталога. Переходим в каталог (если в имени файла есть пробел, то перед ним нужно ставить обратный слеш «\»):

cd ~/.wine/drive_c/Program\ Files/Internet\ Explorer/

И запускаем программу:

wine iexplore.exe

Чтобы не набирать эти команды каждый раз, можно создать простейший скрипт. Переходим в домашний каталог:

cd

Создаем файл ie.sh с помощью редактора nano:

nano ie.sh

Вставляем в файл строчки:

cd ~/.wine/drive_c/Program\ Files/Internet\ Explorer/ wine iexplore.exe

Сохраняем файл — Ctrl+O и выходим из редактора — Ctrl+X. Делаем файл исполняемым:

chmod +x ie.sh

Теперь для запуска ie достаточно набрать:

~/ie.sh

А можно скопировать файл на рабочий стол и запускать его с помощью мышки:

cp ie.sh ~/Desktop/

Установка программы с CD или DVD может быть выполнена с помощью такой команды:

wine start ‘D:\setup.exe’

Аналогичным образом можно установить другие программы и библиотеки. Также можно воспользоваться графическим интерфейсом программы, набрав winetricks без параметров. Потом выбрать «Select the default wineprefix».

Рис. 3. Основное окно winetricks

Далее выбираем действие, которое будем производить, например, установку библиотеки (Install a Windows DLL or component):

Рис. 4. Выбор действия winetricks

И отмечаем галочками библиотеки, которые необходимо установить. Можно сделать то же самое и посредством командой строки, например:

winetricks d3dx9 dotnet20

Таким образом, мы установим сразу два компонента: d3dx9 и dotnet20. Чтобы в программах корректно отображались популярные шрифты, установим их:

winetricks allfonts

С библиотеками немного сложнее. Разные программы могут потребовать отдельных настроек, определенных версий Windows и библиотек. Для этого можно создать несколько конфигураций Wine, указывая каталог с настройками с помощью переменной окружения WINEPREFIX. По умолчанию WINEPREFIX=~/.wine Для создания новых настроек в каталоге ~/.wine2 наберем:

WINEPREFIX=~/.wine2 winecfg

Таким образом, можно создать любое количество конфигураций. Для настройки и установки шрифтов и библиотек наберем:

WINEPREFIX=~/.wine2 winetricks

Для запуска установленной программы:

WINEPREFIX=~/.wine2 ‘C:/путь/к/программе/программа.exe’

Завершить выполнение программы можно с помощью команды:

killall -9 программа.exe

А чтобы завершить работу всех программ, запущенных под Wine, нужно набрать:

wineserver -k

Для удаления настроек и всех программ в префиксе ~/.wine2 нужно просто удалить каталог:

rm -r ~/.wine2

Точно также можно удалить и основной каталог Wine:

rm -r ~/.wine

Будьте внимательны, при этом удалятся также все приложения Windows, которые установлены в этот каталог!

winefile — запуск файлового менеджера, с помощью которого можно запускать Windows-приложения, копировать и удалять файлы и т.д. Узнать, какие приложения и игры запускаются под Wine и как производить настройки под конкретные приложения можно на сайте: http://appdb.winehq.org/ Сайт англоязычный. Для поиска приложений нужно выбрать в меню «Browse Apps» и ввести в поле «Name» название программы. Версии программ, которые запускаются и работают без ошибок или с несущественными проблемами, имеют рейтинг «Platinum» или «Gold». Если программа вообще не работает, то ей присваивается рейтинг «Garbage».

PlayOnLinux

PlayOnLinux — это программа, которая значительно упрощает установку и настройку Windows-приложений для запуска под Wine. Она автоматически скачивает из интернета и устанавливает все необходимые компоненты для запуска конкретных программ, а также и сами программы, если они распространяются бесплатно через интернет. В противном случае, понадобится установочный диск с программой. Устанавливаем программу любым способом, например в Ubuntu командой:

sudo apt-get install playonlinux

и запускаем ее:

playonlinux

Пользоваться программой предельно просто. Нажимаем кнопку «Установка».

Рис. 5. Основное окно PlayOnLinux

Выбираем программу, которую необходимо установить. Если не нашли нужную программу в окне выбора, можно попробовать нажать «Установить программу, отсутствующий в списке» внизу окна.

Рис. 6. Окно выбора программы PlayOnLinux

Останется несколько раз нажать кнопку «Далее», а в некоторых случаях выбрать конфигурацию программы. После установки ярлыки программ появятся в основном окне PlayOnLinux, откуда их можно будет запустить двойным кликом, либо нажатием на кнопку «Запуск». Также можно будет создать ярлыки программ Windows на рабочем столе с помощью кнопки «Ярлык».

Рис. 7. Основное окно PlayOnLinux с установленной Windows-программой FireFox

Прочие программы на базе Wine

Существуют также платные программные продукты на базе Wine. CrossOver позволяет запускать под Linux различные версии Microsoft Office, Adobe Photoshop и множество других программ и игр. WINE@Etersoft нацелен в основном на поддержку популярных программ для бизнеса: 1С:Предприятие, КонсультантПлюс, ГАРАНТ и прочих. Ознакомиться с этими программами можно на официальных сайтах: http://www.codeweavers.com/products/ http://etersoft.ru/products/wine

VirtualBox

VirtualBox — одна из самых популярных программ для виртуализации, которая позволяет запускать различные операционные системы одновременно на одном компьютере. Установку VirtualBox в Ubuntu можно выполнить стандартным способом, набрав в терминале:

sudo apt-get update

sudo apt-get install dkms

sudo apt-get install virtualbox

dkms осуществляет поддержку динамических модулей ядра (vboxdrv, vboxnetflt, vboxnetadp), которые необходимы для работы VirtualBox. В других версиях Linux для установки используются соответствующие команды (yum, urpmi и т. д.), также можно использовать установочный файл или собрать программу из исходного кода. Подробнее смотрите в статье «Как устанавливать программы в Linux». 

Скачать VirtualBox для различных операционных систем можно здесь: https://www.virtualbox.org/wiki/Downloads. После окончания установки добавим пользователя в группу vboxusers, вместо username необходимо указать корректное имя пользователя, под которым будет работать VirtualBox:

sudo usermod -a -G vboxusers username

Теперь можно запустить программу через меню, либо набрав в терминале:

virtualbox

Рис. 8. Менеджер VirtualBox с уже установленными операционными системами

Теперь поставим операционную систему, для этого нужно иметь установочный диск или его образ. Нажмем кнопку «Создать», запустится мастер создания новой виртуальной машины:

Рис. 9. Мастер создания новой виртуальной машины

Нажмем кнопку «Вперед», введем имя виртуальной машины, например «Windows XP», а ниже выберем соответствующие тип и версию операционной системы:

Рис. 10. Выбор версии операционной системы

Мы выбрали Windows XP, поскольку она менее требовательна к ресурсам компьютера, занимает меньше места, быстрее загружается. Но поддержка этой системы уже официально прекращена. Естественно, можно установить и другие версии Windows, которые поддерживает VirtualBox: Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, Windows 8, Windows Server 2012. Далее выбираем объем ОЗУ, которое будет выделено виртуальной машине:

Рис. 11. Выбор объема памяти

Выбор зависит от версии ОС, объема физической памяти, планируемых задач, количества запускаемых одновременно гостевых систем. В зависимости от версии операционной системы, VirtualBox будет предлагать различные параметры по умолчанию, но они, как правило, минимальные, желательно их увеличить. В любом случае, для нормальной работы современных операционных систем необходимо не менее 1-2 Гигабайт ОЗУ (для Windows XP достаточно 512 Мбайт) и еще необходимо оставить память основной хост-системе. Далее создаем новый виртуальный жесткий диск или выбираем уже созданные ранее.

Рис. 12. Виртуальный жесткий диск

На следующем экране выбираем тип диска, по умолчанию стандартный VDI.

Рис. 13. Выбор типа диска

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

Рис. 14. Выбор атрибутов виртуального диска

Указываем размер диска, расположение оставляем по умолчанию (диск будет располагаться в папке ~/VirtualBox VMs/Имя системы.

Рис. 15. Выбор расположения и размера виртуального диска

Осталось нажать кнопку «Создать».

Рис. 16. Последний этап создания новой виртуальной машины

Виртуальная машины создана. Выбираем ее в менеджере VirtualBox и нажимаем кнопку «Свойства».

Рис. 17. Выбор системы

Тут можно подробно настроить созданную виртуальною машину. В первую очередь, необходимо указать диск, с которого будем ставить систему. Для этого нажимаем слева «Носители», выбираем пустой диск, справа кликаем на иконку диска и указываем образ дистрибутива, либо ставим галочку «Живой CD/DVD» и вставляем физический диск.

Рис. 18. Выбор установочного диска

Далее переходим на вкладку «Система → Материнская плата», проверяем порядок загрузки, CD/DVD-ROM должен быть выше жесткого диска. Если это не так, изменяем порядок загрузки стрелками.

Рис. 19. Настройки системы

Если важна скорость работы с графикой, переходим на вкладку «Дисплей», увеличиваем объем видеопамяти и включаем ускорение.

Рис. 20. Настройка параметров дисплея

Переходим обратно в VirtualBox Менеджер и нажимаем кнопку «Старт». Далее производим установку системы, как обычно. После установки гостевой системы, загружаем ее и в меню «Устройства» выбираем «Установить дополнения гостевой ОС». Вместо этого можно нажать комбинацию клавиш правый Ctrl+D. После установки дополнений система будет готова к работе.

Рис. 21. Установленная и готовая к работе система Windows XP в VirtualBox

Загрузка гостевой операционной системы после запуска VirtualBox осуществляется кнопкой «Старт». Переключение указателя мышки между основной и гостевой системой осуществляется автоматически, но можно переключить принудительно с помощью кнопки правый Ctrl (Host key — можно изменить в настройках) и правый Ctrl+I. Эта же кнопка в сочетании с различными клавишами служит для выполнения ряда функций:

Host key+F — переключение в полноэкранный режим и обратно.

Host key+Del — заменяет комбинацию Ctrl+Alt+Del.

Host key+I — отключить интеграцию мышки.

Host key+С — переключение в режим масштабирования, в котором можно задать произвольный размер окна, возврат в стандартный режим происходит с помощью той же комбинации клавиш.

Host key+D — установка дополнений гостевой операционной системы.

Host key+T — сделать снимок, сохранить состояние ОС. Восстановить систему из сохраненного состояния можно будет в основном окне менеджера VirtualBox, нажав на кнопку «Снимки». Очень удобная функция для борьбы с вирусами, тестирования и отладки программ, которые могут повредить систему. Всегда можно сделать откат системы в стабильное состояние.

Host key+S — открыть окно настроек.

Host key+R — перезагрузить систему.

Host key+Q — закрыть виртуальную машину (выйти из системы).

Wine — это свободное программное обеспечение для запуска Windows-приложений на нескольких POSIX-совместимых операционных системах, включая Linux, macOS и BSD.

Если вы любите Linux, то наверняка когда-то запускали Wine. Возможно, для какой-то «важной» программы Windows, у которой нет аналога под Линуксом, или поиграться. Забавный факт: даже Steam Deck от Valve запускает игры через оболочку на основе Wine (она называется Proton).

За последний год я намучился с отладчиком, который позволяет одновременно дебажить и Wine, и Windows-приложение в нём. Разобраться во кишочках Wine оказалось очень интересно! Я-то раньше много им пользовался, но никогда не понимал механику целиком. Можно взять файл Windows — и просто запустить его в Linux без каких-либо изменений. Если вы хотите знать, как это сделано, добро пожаловать под кат.

Дисклеймер. В статье реальность сильно упрощается, а многие детали игнорируются. Текст даёт общее представление, как работает Wine.

© «Время приключений» (1 сезон, 18 серия) — прим. пер.

Wine — не эмулятор!

Прежде чем разбираться в работе Wine, нужно сказать, чем он НЕ является. Вообще, W.I.N.E. — это рекурсивный акроним, который расшифровывается как «Wine Is Not an Emulator». Почему? Потому что есть куча отличных эмуляторов и для старых архитектур, и для современных консолей, а Wine принципиально реализован по-другому. Давайте вкратце рассмотрим, как вообще работают эмуляторы.

Представьте простую игровую приставку, которая понимает две инструкции:

  • push <value> — пушит заданное значение в стек
  • setpxl — достаёт три значения из стека и рисует пиксель с цветом arg1 в точке (arg2, arg3)

(вполне достаточно для визуализации классных демок, верно?)

> dump-instructions game.rom
...
# рисуем красную точку по координатам (10,10)
push 10
push 10
push 0xFF0000
setpxl
# рисуем зелёную точку по координатам (15,15)
push 15
push 15
push 0x00FF00
setpxl

Бинарный файл игры (или картридж ROM) представляет собой последовательность таких инструкций, которые аппаратное обеспечение может загрузить в память и выполнить. Нативное железо выполняет их в натуральном режиме, но как запустить старый картридж на современном ноуте? Для этого делаем эмулятор — программу, которая загружает ROM из картриджа в оперативную память и выполняет его инструкции. Это интерпретатор или виртуальная машина, если хотите. Реализация эмулятора для нашей приставки с двумя инструкциями будет довольно простой:

enum Opcode {
    Push(i32),
    SetPixel,
};

let program: Vec<Opcode> = read_program("game.rom");
let mut window = create_new_window(160, 144); // Виртуальный дисплей 160x144 пикселей
let mut stack = Vec::new(); // Стек для передачи аргументов

for opcode in program {
    match opcode {
        Opcode::Push(value) => {
            stack.push(value);
        }
        Opcode::SetPixel => {
            let color = stack.pop();
            let x = stack.pop();
            let y = stack.pop();
            window.set_pixel(x, y, color);
        }
    }
}

Настоящие эмуляторы намного сложнее, но основная идея та же: поддерживать некоторый контекст (память, регистры и т.д.), обрабатывать ввод (клавиатура/мышь) и вывод (например, рисование в каком-то окне), разбирать входные данные (ROM) и выполнять инструкции одну за другой.

Разработчики Wine могли пойти по этому пути. Но есть две причины, почему они так не поступили. Во-первых, эмуляторы и виртуальные машины тормозные по своей сути — там огромный оверхед на программное выполнение каждой инструкции. Это нормально для старого железа, но не для современных программ (тем более видеоигр, которые требовательны к производительности). Во-вторых, в этом нет необходимости! Linux/macOS вполне способны запускать двоичные файлы Windows нативно, их нужно только немного подтолкнуть…

Давайте скомпилируем простую программу для Linux и Windows и сравним результат:

int foo(int x) {
    return x * x;
}

int main(int argc) {
    int code = foo(argc);
    return code;
}


Слева — Linux, справа — Windows

Результаты заметно отличаются, но набор инструкций фактически один и тот же: push, pop, mov, add, sub, imul, ret.

Если бы у нас был «эмулятор», который понимает эти инструкции, то смог бы выполнить обе программы. И такой «эмулятор» существует — это наш CPU.

Как Linux запускает бинарники

Прежде чем запускать чужеродный двоичный файл, давайте разберёмся, как запускается под Linux родной бинарник.

❯ cat app.cc
#include <stdio.h>

int main() {
  printf("Hello!\n");
  return 0;
}

❯ clang app.cc -o app

❯ ./app
Hello!  # работает!

Довольно просто, но давайте копнём глубже. Если сделать .app?

❯ ldd app
        linux-vdso.so.1 (0x00007ffddc586000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f743fcdc000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f743fed3000)

❯ readelf -l app

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x1050
There are 13 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
...

Самое главное, что .app — это динамически исполняемый файл. Он зависит от некоторых динамических библиотек и требует их присутствия в рантайме. Иначе не запустится. Другой интересный момент — запрос интерпретатора (requesting program interpreter в последней строке листинга). Какой ещё интерпретатор? Я думал, что C++ — компилируемый язык, в отличие от Python…

В данном контексте интерпретатор — это «динамический загрузчик». Специальный инструмент, которая запускает исходную программу: разрешает и загружает её зависимости, а затем передаёт ей управление.

❯ ./app
Hello!  # Работает!

❯ /lib64/ld-linux-x86-64.so.2 ./app
Hello!  # Тоже работает!

# Домашнее задание: запустите это и попробуйте понять смысл выдачи.
❯ LD_DEBUG=all /lib64/ld-linux-x86-64.so.2 ./app

При запуске исполняемого файла ядро Linux определяет, что файл динамический и требует загрузчика. Затем оно запускает загрузчик, который выполняет всю работу. Это можно проверить, если запустить программу под отладчиком:

❯ lldb ./app
(lldb) target create "./app"
Current executable set to '/home/werat/src/cpp/app' (x86_64).
(lldb) process launch --stop-at-entry
Process 351228 stopped
* thread #1, name = 'app', stop reason = signal SIGSTOP
    frame #0: 0x00007ffff7fcd050 ld-2.33.so`_start
ld-2.33.so`_start:
    0x7ffff7fcd050 <+0>: movq   %rsp, %rdi
    0x7ffff7fcd053 <+3>: callq  0x7ffff7fcdd70            ; _dl_start at rtld.c:503:1

ld-2.33.so`_dl_start_user:
    0x7ffff7fcd058 <+0>: movq   %rax, %r12
    0x7ffff7fcd05b <+3>: movl   0x2ec57(%rip), %eax       ; _dl_skip_args
Process 351228 launched: '/home/werat/src/cpp/app' (x86_64)

Мы видим, что первая выполненная инструкция находится в библиотеке ld-2.33.so, а не в бинарнике .app.

Подводя итог, запуска динамически связанного исполняемого файла в Linux выглядит примерно так:

  1. Ядро загружает образ (≈ двоичный файл) и видит, что это динамический исполняемый файл
  2. Ядро загружает динамический загрузчик (ld.so) и передаёт ему управление
  3. Динамический загрузчик разрешает зависимости и загружает их
  4. Динамический загрузчик возвращает управление исходному двоичному файлу
  5. Оригинальный двоичный файл начинает выполнение в _start() и в конечном итоге доходит до main()

Понятно, почему исполняемый файл Windows не запускается в Linux — у него другой формат. Ядро просто не знает, что с ним делать:

❯ ./HalfLife4.exe
-bash: HalfLife4.exe: cannot execute binary file: Exec format error

Однако если пропустить шаги с первого по четвёртый и каким-то образом перескочить на пятый, то теоретически должно сработать, верно? Ведь с точки зрения операционной системы что значит «запустить» бинарный файл?

В каждом исполняемом файле есть раздел .text со списком сериализованных инструкций CPU:

❯ objdump -drS app

app:     file format elf64-x86-64

...

Disassembly of section .text:

0000000000001050 <_start>:
    1050:       31 ed                   xor    %ebp,%ebp
    1052:       49 89 d1                mov    %rdx,%r9
    1055:       5e                      pop    %rsi
    1056:       48 89 e2                mov    %rsp,%rdx
    1059:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    105d:       50                      push   %rax
    105e:       54                      push   %rsp
    105f:       4c 8d 05 6a 01 00 00    lea    0x16a(%rip),%r8        # 11d0 <__libc_csu_fini>
    1066:       48 8d 0d 03 01 00 00    lea    0x103(%rip),%rcx        # 1170 <__libc_csu_init>
    106d:       48 8d 3d cc 00 00 00    lea    0xcc(%rip),%rdi        # 1140 <main>
    1074:       ff 15 4e 2f 00 00       call   *0x2f4e(%rip)        # 3fc8 <__libc_start_main@GLIBC_2.2.5>
    107a:       f4                      hlt
    107b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
...

Чтобы «запустить» бинарный файл, ОС загружает его в память (в частности, раздел .text), устанавливает указатель текущей инструкции на адрес, где находится код, и всё — исполняемый файл типа «запущен». Как сделать это для исполняемых файлов Windows?

Легко! Просто возьмём код из исполняемого файла Windows, загрузим в память, направим %rip в нужное место — и CPU с радостью выполнит этот код! Если архитектура процессора одинаковая, то процессору вообще без разницы, откуда выполнять ассемблерные инструкции.

Hello, Wine!

По сути, Wine — это «динамический загрузчик» для исполняемых файлов Windows. Это родной двоичный файл Linux, поэтому может нормально запускаться, и он знает, как работать с EXE и DLL. То есть своего рода эквивалент ld-linux-x86-64.so.2:

# запуск бинарника ELF
❯ /lib64/ld-linux-x86-64.so.2 ./app

# запуск бинарника PE
❯ wine64 HalfLife4.exe

Здесь wine64 загружает исполняемый файл Windows в память, анализирует его, выясняет зависимости, определяет, где находится исполняемый код (т. е. раздел .text), и переходит в этот код.

Примечание. В действительности он переходит к чему-то вроде ntdll.dll!RtlUserThreadStart(), это точка входа в «пространство пользователя» в мире Windows. Потом в mainCRTStartup() (эквивалент _start), и в сам main().

На данный момент наша Linux-система выполняет код, изначально скомпилированный для Windows, и всё вроде бы работает. За исключением системных вызовов.

Системные вызовы

Системные вызовы (syscall) — вот где основные сложности. Это вызовы к функциям, которая реализованы не в бинарнике или динамических библиотеках, а в родной ОС. Набор системных вызовов представляет системный API операционной системы. В нашем случае это Windows API.

Примеры системных вызовов в Linux: read, write, open, brk, getpid

Примеры в Windows: NtReadFile, NtCreateProcess, NtCreateMutant 😱

Системные вызовы не являются обычными вызовами функций в коде. Открытие файла, например, должно выполняться самим ядром, поскольку именно оно следит за файловыми дескрипторами. Поэтому приложению нужен способ как бы «прервать своё выполнение» и передать управление ядру (эта операция обычно называется переключением контекста).

Набор системных функций и способы их вызова в каждой ОС разные. Например, в Linux для вызова функции read() наш бинарник записывает в регистр %rdi дескриптор файла, в регистр %rsi — указатель буфера, а в %rdx — количество байт для чтения. Однако в ядре Windows нет функции read()! Ни один из аргументов не имеет там смысла. Бинарник Windows использует свой способ выполнения системных вызовов, который не сработает в Linux. Не будем здесь углубляться детали системных вызовов, например, вот отличная статья о реализации в Linux.

Скомпилируем ещё одну небольшую программу и сравним сгенерированный код в Linux и Windows:

#include <stdio.h>

int main() {
    printf("Hello!\n");
    return 0;
}


Слева — Linux, справа — Windows

На этот раз мы вызываем функцию из стандартной библиотеки, которая в конечном итоге выполняет системный вызов. На скриншоте выше версия Linux вызывает puts, а версия Windows — printf. Эти функции из стандартных библиотек (libc.so в Linux, ucrtbase.dll в Windows) для упрощения взаимодействия с ядром. Под Linux сейчас частенько собирают статически связанные бинарники, не зависимые от динамических библиотек. В этом случае реализация puts встроена в двоичный файл, так что libc.so не задействуется в рантайме.

Под Windows до недавнего времени «системные вызовы bcgjkmpjdfkb только вредоносные программы»[нет источника] (вероятно, это шутка автора — прим. пер.). Обычные приложения всегда зависят от kernel32.dll/kernelbase.dll/ntdll.dll, где скрывается низкоуровневая магия тайного общения с ядром. Приложение просто вызывает функцию, а библиотеки заботятся об остальном:


источник

В этом месте вы наверное поняли, что будет дальше. 😏

Трансляция системных вызовов в рантайме

А что, если «перехватывать» системные вызовы во время выполнения программы? Например, когда приложение вызывает NtWriteFile(), мы берём управление на себя, вызываем write(), а потом возвращаем результат в ожидаемом формате — и возвращаем управление. Должно сработать. Быстрое решение в лоб для примера выше:

// HelloWorld.exe
lea     rcx, OFFSET FLAT:`string'
call    printf
  ↓↓
// «Фальшивый» ucrtbase.dll
mov edi, rcx   // Преобразование аргументов в Linux ABI
call puts@PLT  // Вызов реальной реализации Linux
  ↓↓
// Real libc.so
mov rdi, <stdout>  // запись в STDOUT
mov rsi, edi       // указатель на "Hello"
mov rdx, 5         // сколько символов писать
syscall

По идее, можно сделать собственную версию ucrtbase.dll со специальной реализацией printf. Вместо обращения к ядру Windows она будет следовать формату интерфейсов Linux ABI и вызывать функцию write из библиотеки libc.so. Однако на практике мы не можем изменять код этой библиотеки по ряду причин — это муторно и сложно, нарушает DRM, приложение может статически ссылаться на ucrtbase.dll и т. д.

Поэтому вместо редактирования бинарника мы внедримся в промежуток между исполняемым файлом и ядром, а именно в ntdll.dll. Это «ворота» в ядро, и Wine действительно предоставляет собственную реализацию. В последних версиях Wine решение состоит из двух частей: ntdll.dll (библиотека PE) и ntdll.so (библиотека ELF). Первая часть — это тоненькая прокладка, которая просто перенаправляет вызовы в ELF-аналог. А уже он содержит специальную функцию __wine_syscall_dispatcher, которая выполняет магию преобразования текущего стека из Windows в Linux и обратно.

Поэтому в Wine системный вызов выглядит следующим образом:

Диспетчер системных вызовов — это мост между мирами Windows и Linux. Он заботится о соглашениях и стандартах для системных вызовов: выделяет пространство стека, перемещает регистры и т. д. Когда выполнение переходит к библиотеке Linux (ntdll.so), мы можем свободно использовать любые нормальные интерфейсы Linux (например, libcили syscall), реально читать/записывать файлы, занимать/отпускать мьютексы и так далее.

И это всё?

Звучит почти слишком просто. Но так и есть. Во-первых, под Windows много разных API. Они плохо документированы и имеют известные (и неизвестные, ха-ха) ошибки, которые следует воспроизвести в точности. (Вспомните, как при разработке Windows 95 туда скопировали утечку памяти из SimCity, чтобы популярная игра не крашилась в новой ОС. Возможно, такие специфические вещи приходится воспроизводить под Linux для корректной работы конкретных программ — прим. пер.). Большая часть исходного кода Wine — это реализация различных Windows DLL.

Во-вторых, системные вызовы можно выполнять по-разному. Технически ничто не мешает Windows-приложению выполнить прямой системный вызов через syscall, и в идеале это тоже должно работать (как мы уже говорили, Windows-игры делают всякие безумные вещи). В ядре Linux специальный механизм для обработки таких ситуаций, который, конечно, добавляет сложности.

В-третьих, весь этот бардак 32 vs 64 бит. Есть много старых 32-битных игр, которые никогда не перепишут на 64 бита. В Wine есть поддержка обеих платформ. И это тоже плюс к общей сложности.

В-четвертых, мы даже не упомянули wine-server — отдельный процесс Wine, который поддерживает «состояние» ядра (открытые дескрипторы файлов, мьютексы и т. д.).

И последнее… о, так вы хотите запустить игру? А не просто hello world? Ну так это совсем другое дело! Тогда нужно разобраться с DirectX, со звуком (привет, PulseAudio, старый друг), устройствами ввода (геймпады, джойстики) и т. д. Куча работы!

Wine разрабатывался в течение многих лет и прошёл долгий путь. Сегодня вы без проблем запускаете под Linux самые последние игры, такие как Cyberpunk 2077 или Elden Ring. Чёрт возьми, иногда производительность Wine даже выше, чем у Windows! В какое замечательное время мы живём…


P. S. На всякий случай повторим дисклеймер: статья даёт только базовое представление о работе Wine. Многие детали упрощены или опущены. Так что не судите очень строго, пожалуйста.

  • Как запустить программу для windows на ubuntu
  • Как запустить программу для windows на linux
  • Как запустить программу для windows на android
  • Как запустить программу для mac os на windows
  • Как запустить программу восстановления системы windows 7