Как запустить исполняемый файл Windows из WSL (Ubuntu) Bash

Наряду с обновлением Windows 10 Anniversary для лета 2016 года появилась возможность запуска двоичных файлов ubuntu внутри новой Windows Subsystem for Linux (WSL), "облегченной" виртуализированной подсистемы.

К сожалению, запуск C:\Windows\System32\bash.exe, другой bash Бинарный файл ELF запускает процесс внутри WSL, откуда вы не можете убежать! Вы можете запускать только другие двоичные файлы ELF.

Так как я могу выполнить *.exe файлы из Windows Bash? [1]

[1] Вопрос задан также в "официальном" репозитории поддержки GH от Microsoft.

6 ответов

Решение

Родное решение

Официальное решение, предоставляемое Windows 10 Insider Preview Update (14951), основано на почти забытом средстве Linux binfmt_msc для запуска двоичных файлов. Команда регистрации для binfmt_misc будет такой (где /init является временным "интерпретатором" binfmt_misc для win-исполняемых файлов):

sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register

И тогда win-исполняемый файл будет запускаться как обычные программы:

$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir

Не то чтобы любой исполняемый файл win должен находиться в файловой системе Windows (DrvFs), а не в файловой системе Linux (VolFs), чтобы наследовать правильный рабочий каталог Windows.

Альтернатива cbwin

Пока вы не получите последнюю сборку, проект cbwin предлагает обходной путь, установив 3 новые команды linux внутри WSL:

  • wcmd: вызвать win-исполняемый файл через cmd.exe,
  • wrun: вызвать win-исполняемый файл синхронно с CreateProcess и ждать, чтобы умереть (не используя cmd.exe).
  • wstart: запустить отдельную (асинхронную) команду (с использованием cmd.exe).

Чтобы их использовать, вы должны:

  1. Установите cbwin:
    • новый outbash.exe будет установлен в вашей обычной файловой системе Windows (где-то в вашем %PATH%), плюс
    • 3 linux-команды в файловой системе WSL.
  2. Использовать этот outbash.exe (где бы вы его не установили) для запуска WSL, НЕ C:\Windows\System32\bash.exe!
  3. Префикс любых исполняемых файлов win с одной из этих команд, например wrun notepad,

Совет: если исполняемый файл запущен с wcmd или же wrun порождает детей, они выживают только до тех пор, пока исполняемый файл остается живым.

Другими словами, пытаясь начать notepad.exe с wcmd не будет работать, потому что блокнот будет убит сразу после запуска - Используйте wrun (синхронно) или wstart (асинхронно) в этом случае.

В Windows 10 Creators Update (сборка 1703, апрель 2017 г.) это поддерживается изначально. Теперь вы можете запускать бинарные файлы Windows из Linux...

https://msdnshared.blob.core.windows.net/media/2017/04/4-interop.png

...и наоборот:

https://msdnshared.blob.core.windows.net/media/2017/04/5-interop-bash.png

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

Почему бы просто не использовать

$ powershell.exe Start filename

Start эквивалент Windows xdg-open на большинстве Linux или openв macOS, что означает "открыть с настольным приложением по умолчанию". Мне нравится использовать псевдоним, чтобы открыть.

Я использую псевдоним.

      alias aws="/mnt/c/Program\ Files/Amazon/AWSCLIV2//aws.exe"
alias kubectl="/mnt/c/ProgramData/chocolatey/bin/kubectl.exe"
alias kubectx="/mnt/c/ProgramData/chocolatey/bin/kubectx.exe"
alias kubens="/mnt/c/ProgramData/chocolatey/bin/kubens.exe"
alias pytest=pytest.exe

Пока работает .exe из командной строки работает, при запуске из скажем PHP через exec() Я не мог заставить это работать. Добавление /init Однако работает. Это моя работа /usr/local/bin/convert файл для GraphicsMagick, установленный в Windows:

#!/bin/sh
/init "$(ls /mnt/c/Program*/GraphicsMagick*/gm.exe|tail -1)" convert "$@"

Меня это немного сбивает с толку. Я добавил символическую ссылку:

$ ls -l /c                                                                                               
lrwxrwxrwx 1 root root 5 Dec  3 10:24 /c -> mnt/c  

теперь ls / c дает тот же результат, что и ls /mnt / c

Но теперь: /c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version ==> ничего

Однако:

/mnt/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe  -version 
java version "1.8.0_211"                                                                                                Java(TM) SE Runtime Environment (build 1.8.0_211-b12)                                                                   Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode) 

То же самое происходит и с другими исполняемыми файлами Windows. Есть ли в WSL ошибка при реализации символических ссылок?

Другие вопросы по тегам