【发布时间】:2011-05-14 18:46:14
【问题描述】:
我有一个使用 WINE 在 Linux 上运行的 windows 程序。
如何从 windows 程序调用 Linux shell 命令?
【问题讨论】:
-
那个 Windows 程序是什么?
-
如果您使用 Windows API 执行进程,但通过映射到该文件系统的任何驱动器号将 linux 可执行文件作为目标,会发生什么情况?
我有一个使用 WINE 在 Linux 上运行的 windows 程序。
如何从 windows 程序调用 Linux shell 命令?
【问题讨论】:
使用较新的 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 调用它会失败!
【讨论】:
试试这个(在我的 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.
试试(这里 yourprogram 是你想在 wine 中执行的 linux/unix 程序)
ln -s /path/to/yourprogram /path/to/wineprefix/drive_c/windows/system32/yourprogram
这就是我让 java 工作的方式。
【讨论】:
如何从 Wine 程序调用 Linux 程序——API 方面的五点。
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 更新,它就会被恢复。
默认情况下,您可能需要指定可执行文件的完整(或相对)路径(例如,/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。
无法从 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.
父 Wine 进程不能等待(例如,通过WaitForSingleObject)子 Linux 进程,因为它没有提供子进程句柄 - 它只是 0。请参阅错误报告:CreateProcess doesn't set hProcess correctly when starting a Linux program(状态:CLOSED WONTFIX)。
尽管如此,如果子进程使用 stdout(另见下文),则父进程可以通过在某个管道上阻塞读取来间接等待子进程。
也许这是 Wine 中的一个错误,但父进程应该关闭 std 句柄,这些句柄传递给 CreateProcess,只有在关闭相应管道的自己的句柄之后(或就在它之前)。而在 Windows 中,这些句柄可以在 CreateProcess 函数完成后关闭。通过 MSDN,这些句柄可能会在通过后立即关闭(请参阅CreateProcess function):
STARTUPINFO 或 STARTUPINFOEX 中的句柄必须用 不再需要时关闭句柄。
在Wine 2.0.1 中,子Linux 进程中对应的管道在这种情况下会立即关闭,子进程会提前停止。但在子 Windows 进程的情况下则不然。
【讨论】:
cmd.exe),是 cmd.exe 处理管道,并且它正确地处理它们(至少在葡萄酒 2.0.1)。第 5 点是关于使用 Windows API(即 CreateProcess 函数)运行 Linux 应用程序并且应该自己处理管道的情况。
start /unix /usr/bin/git 或 start /unix /usr/bin/ffmpeg 获得任何输出?
/bin/ls。不要使用start,它不适合运行Linux命令(即cli-application)。如果您需要在新窗口中启动命令,请使用 cmd 包装器,例如:start cmd /k /bin/ls
start,但start /unix 不是运行Linux 命令的给定方式吗?这不是原发帖人的问题吗?
【讨论】:
对我来说,我发现on this site 的第一个解决方案是有效的——将扩展与 winebrowser 相关联,当在 wine explorer(或其他 Windows 应用程序)中单击文件时,默认的 gnome 文件查看器会从 wine 启动。
以前的shell 脚本解决方案,在 wine 1.4 中工作,不适用于 wine 1.6。
但是,我注意到的问题是 Windows 编码中的名称未转换为 Linux 语言环境,从而阻止了它与例如俄语目录名称
【讨论】:
编辑: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 更改为您安装它的位置。
【讨论】:
listed on WineHQ FAQ的shell脚本可以稍作修改,例如:
#!/bin/bash
WFILE=$(echo -E $2)
FILE=$(wine winepath $WFILE)
$1 $FILE
其余部分的工作方式与常见问题解答中的描述相同。
【讨论】:
cmd /c start /unix open /Applications/Calculator.app(或在 OS X 终端中工作的任何其他命令)。请问有人有最新的信息吗?
我喜欢Far Commander,它确实在wine下运行,所以我设置了这两个脚本:
C:\windows\xt.bat
start /unix /usr/bin/xterm -e %*
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 环境中得到结果。
【讨论】:
如果您需要等待命令完成并获取其输出,请使用 SSH。否则(如果您只需要启动它)这些方法中的任何一个都可以工作:
核心问题是CreateProcess返回zero PID and handle,所以你不能等待子进程完成并得到它的退出码。
我也试过standard pipes redirection,但没有成功。 Linux子进程输出丢失,管道为空。
因此,对于 CreateProcess 和朋友,您必须使用某种 trigger files,它看起来不太漂亮。就像我说的,我们将改用 SSH。
【讨论】: