【问题标题】:Execute Shell Commands from Program running in WINE从在 WINE 中运行的程序执行 Shell 命令
【发布时间】:2011-05-14 18:46:14
【问题描述】:

我有一个使用 WINE 在 Linux 上运行的 windows 程序。

如何从 windows 程序调用 Linux shell 命令?

【问题讨论】:

  • 那个 Windows 程序是什么?
  • 如果您使用 Windows API 执行进程,但通过映射到该文件系统的任何驱动器号将 linux 可执行文件作为目标,会发生什么情况?

标签: linux shell wine


【解决方案1】:

使用较新的 Wine 版本(使用 Wine 1.7.38 测试),您可以通过以下方式在 Wine 中运行 Linux 程序(此处以启动 gedit 为例):

wineconsole cmd

...从那个葡萄酒控制台:

start /unix /usr/bin/gedit

如果您想直接从 Windows 应用程序中启动 Linux 程序,以下行确实对我有用:

cmd /c start /unix /usr/bin/gedit

要对此进行测试,您可以直接在 Linux 控制台上调用:

wine cmd /c start /unix /usr/bin/gedit

需要注意的重要一点:要启动的程序需要设置可执行位,否则从 Wine 调用它会失败!

【讨论】:

  • 这适用于 ui 应用程序,但我似乎无法让它与任何命令行应用程序一起工作 - 即 ffmpeg、git 等。它没有显示错误,也没有任何输出.根本不值一提。其他人有运气吗?
【解决方案2】:

试试这个(在我的 Linux Mint 系统上运行 Gnome 计算器):

wineconsole cmd

...从葡萄酒控制台:

/bin/sh gcalctool

根据这个一般原则,您还可以通过编辑 wine 注册表来打开文档并将文件与 linux 应用程序关联。葡萄酒常见问题解答中有一段关于它的内容:

6.6.3 How do I associate a native program with a file type in Wine?

所以你应该能够编写 shell 脚本并调用它们 OK。

【讨论】:

  • 这似乎不再起作用,只需获取Can't recognize /bin/sh as an internal or external command, or batch script.
  • 它现在可以正常工作了,除了似乎没有效果的 DDE 错误。
【解决方案3】:

试试(这里 yourprogram 是你想在 wine 中执行的 linux/unix 程序)

ln -s /path/to/yourprogram /path/to/wineprefix/drive_c/windows/system32/yourprogram

这就是我让 java 工作的方式。

【讨论】:

  • 这似乎不适用于某些(?)命令行应用程序 - 即 ffmpeg、git 等。它没有显示错误,也没有任何输出。根本不值一提。你有什么不同吗?
【解决方案4】:

如何从 Wine 程序调用 Linux 程序——API 方面的五点。

1。妥妥的PATHEXT

在新的 Wine 版本中(至少从 2.0.1 开始),需要在 @987654330 的可执行文件扩展名列表中添加 empty 扩展名(即仅点字符:.) @ 环境变量。如果没有此添加,错误消息可能会显示如下内容:

Can't recognize '/bin/bash' as an internal or external command, or batch script.

要修复注册表中的初始 PATHEXT 值,可以使用以下命令 sn-p(针对每个 WINEPREFIX):

k='HKLM\System\CurrentControlSet\Control\Session Manager\Environment'
pathext_orig=$( wine reg query "$k" /v PATHEXT | tr -d '\r' | awk '/^  /{ print $3 }' )
echo "$pathext_orig" | grep -qE '(^|;)\.(;|$)' \
  || wine reg add "$k" /v PATHEXT /f /d "${pathext_orig};."

此代码仅检查并修改 PATHEXT 是否不包含 . 项。

另见:How do I launch native applications from a Windows application? 在 WineHQ 常见问题解答中; 注意:

请注意,每次升级时都必须进行此更改 Wine,因为只要 wineprefix 更新,它就会被恢复。

2。可执行文件路径

默认情况下,您可能需要指定可执行文件的完整(或相对)路径(例如,/bin/bash),因为 Wine 进程不会从父进程继承 PATH 环境变量Linux 进程。 请注意,Wine 进程中的当前驱动器默认映射到 Linux 根文件夹,因此无需指定驱动器号。 IE。 /bin/bash 有效,但 bash 无效。

另一种方法是相应地更改Wine 中的PATH 环境变量,或者更改当前目录。

当路径包含非 ASCII 字符时——作为 CreateProcessA 的参数——路径应该在 Wine 语言环境中并根据 LANG 环境变量;另请参阅本主题中的answer by Eugene,以及如何set encoding to use with non-Unicode application in Wine 的论坛帖子。对于CreateProcessW,无论如何路径都应该是UTF-16。

3。可执行格式

无法从 Wine 执行共享对象格式的 Linux 可执行文件。请参阅:Executables vs Shared objects 和 How to execute shell scripts from 32-bit Wine on 64-bit Linux。例如,/bin/dash 可以是“ELF 64 位 LSB 共享对象”(参见file /bin/dash 的输出),在这种情况下不能从 Wine 执行。错误信息说:

wine: Bad EXE format for Z:\bin\dash..
Can't recognize '/bin/dash' as an internal or external command, or batch script.

4。无需等待

父 Wine 进程不能等待(例如,通过WaitForSingleObject)子 Linux 进程,因为它没有提供子进程句柄 - 它只是 0。请参阅错误报告:CreateProcess doesn't set hProcess correctly when starting a Linux program(状态:CLOSED WONTFIX)。

尽管如此,如果子进程使用 stdout(另见下文),则父进程可以通过在某个管道上阻塞读取来间接等待子进程。

5。管道重定向的区别

也许这是 Wine 中的一个错误,但父进程应该关闭 std 句柄,这些句柄传递给 CreateProcess,只有在关闭相应管道的自己的句柄之后(或就在它之前)。而在 Windows 中,这些句柄可以在 CreateProcess 函数完成后关闭。通过 MSDN,这些句柄可能会在通过后立即关闭(请参阅CreateProcess function):

STARTUPINFO 或 STARTUPINFOEX 中的句柄必须用 不再需要时关闭句柄。

在Wine 2.0.1 中,子Linux 进程中对应的管道在这种情况下会立即关闭,子进程会提前停止。但在子 Windows 进程的情况下则不然。

【讨论】:

  • 我无法让任何命令行 Linux 应用程序从 Wine 运行(即 ffmpeg、git 等)——它没有显示错误,也没有任何输出。根本不值一提。我猜这可能与您的第 5 点有关:子 Linux 进程中的管道将立即关闭,子进程将过早停止。有没有解决方法 - 即。某种方式我可以从 WINE 调用 Linux ffmpeg?
  • @Metal450,当您从 Wine 命令行运行 Linux cli 应用程序时(例如 cmd.exe),是 cmd.exe 处理管道,并且它正确地处理它们(至少在葡萄酒 2.0.1)。第 5 点是关于使用 Windows API(即 CreateProcess 函数)运行 Linux 应用程序并且应该自己处理管道的情况。
  • 从 cmd.exe 中,您是否能够从 start /unix /usr/bin/git 或 start /unix /usr/bin/ffmpeg 获得任何输出?
  • 试试/bin/ls。不要使用start,它不适合运行Linux命令(即cli-application)。如果您需要在新窗口中启动命令,请使用 cmd 包装器,例如:start cmd /k /bin/ls
  • 对不起,我不太明白那个答案。我正在尝试专门从 WINE 调用 ffmpeg - 作为最初的概念证明,我试图从 cmd 运行它,但看不到任何输出。您说不要使用start,但start /unix 不是运行Linux 命令的给定方式吗?这不是原发帖人的问题吗?
【解决方案5】:

例如:

Z:\bin\ls

但也许您正在寻找类似http://gnuwin32.sourceforge.net/ 的东西,您将安装到您的葡萄酒“windows”中?或者已经提到的cygwin。

【讨论】:

    【解决方案6】:

    对我来说,我发现on this site 的第一个解决方案是有效的——将扩展与 winebrowser 相关联,当在 wine explorer(或其他 Windows 应用程序)中单击文件时,默认的 gnome 文件查看器会从 wine 启动。

    以前的shell 脚本解决方案,在 wine 1.4 中工作,不适用于 wine 1.6。

    但是,我注意到的问题是 Windows 编码中的名称未转换为 Linux 语言环境,从而阻止了它与例如俄语目录名称

    【讨论】:

      【解决方案7】:

      编辑:user1182474 的评论是正确的; Wine 不会隔离它运行的程序。 (它试图隐藏它,但不是很彻底。)我在使用谷歌时完全失败了。 Psen 下面的评论更正确,并引用了常见问题解答。 (请注意,要使其正常工作,您可能需要通过 Wine 驱动器映射提供程序目录。或者,请参阅匿名回复者的答案。)

      == 旧答案 ==

      Wine 隔离它运行的程序。如果所有应用程序都按预期工作,那么这些应用程序将提供一个与 Windows 没有区别的环境。不幸的是,出于您的目的,这意味着您无法访问主机操作系统 (Linux) 的功能。我的意思是,你可以修补 Wine 来做到这一点,但我的印象是它的工作量大于它的价值。

      有希望! Cygwin 是用于 Windows 的类 Unix 环境。您可以在 Wine 中安装 Cygwin,并使用 Cygwin 运行您的 shell 脚本。 (显然,使用 'winetricks cygwin' 安装是最简单的)像这样调用 Cygwin 的 bash shell(在一些 Wine 程序中):

      c:\cygwin\bin\bash  myscript
      

      当然,将 c:\cygwin 更改为您安装它的位置。

      【讨论】:

      • Wine 根本不会隔离它运行的程序......如果可以的话,我会否决这个。
      • @user1182474 哇,真是个疏忽。你说得对。我已经编辑了我的答案。
      【解决方案8】:

      listed on WineHQ FAQ的shell脚本可以稍作修改,例如:

      #!/bin/bash
      WFILE=$(echo -E $2)
      FILE=$(wine winepath $WFILE)
      $1 $FILE
      

      其余部分的工作方式与常见问题解答中的描述相同。

      【讨论】:

      • 我无法让任何这些方法在 OS X 下运行的当前 (1.8/1.9) Wine 下工作。我可以打开 wineconsole,但我试图找到某种方式来运行(例如)OS X 计算器。这不起作用:cmd /c start /unix open /Applications/Calculator.app(或在 OS X 终端中工作的任何其他命令)。请问有人有最新的信息吗?
      • @emendelson /Applications/Calculator.app 是真正的应用程序位于 /Application/Calculator.app/Contents/MacOS 中的文件夹。您可以通过打开控制台并输入“ls /Application”来浏览内容/Calculator.app/Contents/MacOS”在那里。
      【解决方案9】:

      我喜欢Far Commander,它确实在wine下运行,所以我设置了这两个脚本:

      1. 从 Windows 启动 Linux 应用程序

      C:\windows\xt.bat

      start /unix /usr/bin/xterm -e %*
      
      1. 从 wine 环境(Far)在 Linux 中打开文件:

      C:\windows\xdg.bat

      cd >C:\windows\command\mypwd
      start /unix /etc/init.d/winopen.sh  %*
      

      /etc/init.d/winopen.sh

      #!/bin/sh
      PWDF=`winepath -u 'C:\windows\command\mypwd'`
      fromdos $PWDF
      xdg-open $(winepath -u $(cat $PWDF)/$1)
      

      现在我可以在 Far 命令行上输入:

      xt 顶部

      xdg SomeDocument.PDF

      并在 Linux 环境中得到结果。

      【讨论】:

        【解决方案10】:

        如果您需要等待命令完成并获取其输出,请使用 SSH。否则(如果您只需要启动它)这些方法中的任何一个都可以工作:

        核心问题是CreateProcess返回zero PID and handle,所以你不能等待子进程完成并得到它的退出码。

        我也试过standard pipes redirection,但没有成功。 Linux子进程输出丢失,管道为空。

        因此,对于 CreateProcess 和朋友,您必须使用某种 trigger files,它看起来不太漂亮。就像我说的,我们将改用 SSH。

        【讨论】:

        • 你究竟是如何“使用 SSH”来获取程序的输出的?
        • PLINK.EXE -i -no-antispoof @localhost
        猜你喜欢
        • 2014-03-06
        • 2011-02-06
        • 1970-01-01
        • 2011-08-02
        • 1970-01-01
        • 1970-01-01
        • 2011-06-15
        • 2011-07-18
        • 1970-01-01
        相关资源
        最近更新 更多