简体   繁体   English

从在 WINE 中运行的程序执行 Shell 命令

[英]Execute Shell Commands from Program running in WINE

I have a windows program running on Linux using WINE.我有一个使用 WINE 在 Linux 上运行的 Windows 程序。

How can I call Linux shell commands from the windows program?如何从 Windows 程序调用 Linux shell 命令?

With newer Wine versions (tested with Wine 1.7.38) , you can run a Linux program from within Wine in the following way (here to launch gedit, as an example):使用较新的 Wine 版本(使用 Wine 1.7.38 测试) ,您可以通过以下方式在 Wine 中运行 Linux 程序(这里以启动 gedit 为例):

wineconsole cmd

...and from that wine console: ...从那个葡萄酒控制台:

start /unix /usr/bin/gedit

If you want to launch a Linux program directly from within a Windows-application, the following line did work for me:如果您想直接从 Windows 应用程序中启动 Linux 程序,以下行对我有用:

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

To test this, you can call directly on your Linux console this:要对此进行测试,您可以直接在 Linux 控制台上调用:

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

One important thing to Note: the program you want to start needs to have the executable bit set, otherwise calling it from Wine will fail!需要注意的一件重要事情:您要启动的程序需要设置可执行位,否则从 Wine 调用它会失败!

Try this (runs Gnome calculator on my Linux Mint system):试试这个(在我的 Linux Mint 系统上运行 Gnome 计算器):

wineconsole cmd

...and from the wine console: ...从葡萄酒控制台:

/bin/sh gcalctool

On this general principle, you can also open documents and associate files with a linux app by editing the wine registry.根据这个一般原则,您还可以通过编辑 wine 注册表来打开文档并将文件与 linux 应用程序关联。 There is a section about it in the wine FAQ:在葡萄酒常见问题中有一个关于它的部分:

6.6.3 How do I associate a native program with a file type in Wine? 6.6.3 如何在 Wine 中关联本地程序和文件类型?

So you should be able to write shell scripts and call them OK.所以你应该能够编写 shell 脚本并调用它们。

How to call a Linux program from a Wine program — five points in terms of API.如何从 Wine 程序调用 Linux 程序——API 方面的五点。

1. Proper PATHEXT 1. 正确的PATHEXT

In the new Wine versions (since 2.0.1 at least) it is need to add empty extension (ie just dot character: . ) into the list of executable file extensions in PATHEXT environment variable.在新的 Wine 版本中(至少从 2.0.1 开始),需要在PATHEXT环境变量中的可执行文件扩展名列表中添加扩展名(即只是点字符: . )。 Without this addition an error message can say something like:如果没有此添加,错误消息可能会显示如下内容:

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

To fix the initial PATHEXT value in the registry the following commands snippet can be used (for each WINEPREFIX ):要修复注册表中的初始PATHEXT值,可以使用以下命令片段(对于每个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};."

This code checks and then modifies PATHEXT if it doesn't contain .此代码检查然后修改PATHEXT如果它不包含. item only.仅项目。

See also: How do I launch native applications from a Windows application?另请参阅: 如何从 Windows 应用程序启动本机应用程序? in WineHQ FAQ;在 WineHQ 常见问题解答中; NB :注意

Note that this change will have to be made every time you upgrade Wine, as it will be reverted whenever the wineprefix is updated.请注意,每次升级 Wine 时都必须进行此更改,因为只要更新 wineprefix,它就会恢复。

2. Path to executable 2. 可执行文件路径

It is likely that by default you will need to specify the full (or relative) path to an executable file (for example, /bin/bash ), since a Wine process doesn't inherit PATH environment variable from the parent Linux process.默认情况下,您可能需要指定可执行文件的完整(或相对)路径(例如, /bin/bash ),因为 Wine 进程不会从父 Linux 进程继承PATH环境变量。 Note that the current drive in a Wine process is mapped to the Linux root folder by default, so no need to specify a drive letter.请注意,Wine 进程中的当前驱动器默认映射到 Linux 根文件夹,因此无需指定驱动器号。 Ie /bin/bash just works, but not bash ./bin/bash只是有效,但不是bash

Another way is to alter PATH environment variable in Wine accordingly, or to change the current directory.另一种方法是相应地更改 Wine 中的PATH环境变量,或更改当前目录。

Whenever a path contains non-ASCII characters — as argument of CreateProcessA — the path should be in Wine locale and according to LANG environment variable;当路径包含非 ASCII 字符时——作为CreateProcessA参数——路径应该在 Wine 语言环境中并根据LANG环境变量; see also the answer by Eugene in this topic, and a forum post how to set encoding to use with non-Unicode application in Wine .另请参阅Eugene在本主题中的回答,以及如何设置编码以与 Wine 中的非 Unicode 应用程序一起使用的论坛帖子。 For CreateProcessW the path should be in UTF-16 in any case.在任何情况下,对于CreateProcessW ,路径都应该是 UTF-16。

3. Executable format 3. 可执行格式

Linux executables in shared object format cannot be executed from Wine.共享对象格式的 Linux 可执行文件不能从 Wine 执行。 See: Executables vs Shared objects and How to execute shell scripts from 32-bit Wine on 64-bit Linux .请参阅: 可执行文件与共享对象以及如何在 64 位 Linux 上从 32 位 Wine 执行 shell 脚本 For example, /bin/dash can be "ELF 64-bit LSB shared object" (see output of file /bin/dash ) and cannot be executed from Wine in such case.例如, /bin/dash可以是“ELF 64 位 LSB 共享对象”(参见file /bin/dash输出)并且在这种情况下不能从 Wine 执行。 Error message says:错误信息说:

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

4. No waiting 4.无需等待

A parent Wine process cannot wait (for example, via WaitForSingleObject ) on a child Linux process since it isn't provided with the child process handle — it is just 0. See bugreport: CreateProcess doesn't set hProcess correctly when starting a Linux program (Status: CLOSED WONTFIX).父 Wine 进程不能在子 Linux 进程上等待(例如,通过WaitForSingleObject ),因为它没有提供子进程句柄——它只是 0。请参阅错误报告:启动 Linux 程序时 CreateProcess 没有正确设置 hProcess (状态:关闭 WONTFIX)。

Nevertheless a parent process can indirectly wait a child process via blocking read on the certain pipe if the child process uses stdout (see also bellow).然而,如果子进程使用 stdout(另见下文),父进程可以通过在特定管道上阻塞读取来间接等待子进程。

5. Difference in pipes redirection 5.管道重定向的区别

Perhaps it is a bug in Wine, but a parent process should close the std handles, that are passed into CreateProcess, only after close the own handles (or just before it) for the corresponding pipes.也许这是 Wine 中的一个错误,但是父进程应该关闭传递给 CreateProcess 的 std 句柄,只有在关闭相应管道的自己的句柄(或就在它之前)之后。 While in Windows these handles can be closed just after CreateProcess function is completed.而在 Windows 中,这些句柄可以在CreateProcess函数完成后立即关闭。 By MSDN these handles may be closed at once after passing (see CreateProcess function ):通过 MSDN,这些句柄可能会在传递后立即关闭(请参阅CreateProcess 函数):

Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed. STARTUPINFO 或 STARTUPINFOEX 中的句柄在不再需要时必须用 CloseHandle 关闭。

In Wine 2.0.1, the corresponding pipe in a child Linux process will be closed immediately in such case, and the child process will prematurely stop .在 Wine 2.0.1 中,Linux 子进程中对应的管道会立即关闭,子进程会提前停止 But not in the case of a child Windows process.但不是在子 Windows 进程的情况下。

Try (where yourprogram is the linux/unix program you want to execute in wine)尝试(其中 yourprogram 是您要在 wine 中执行的 linux/unix 程序)

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

That is how I have gotten java working.这就是我让java工作的方式。

For example:例如:

Z:\bin\ls

But maybe you are looking rather for something like http://gnuwin32.sourceforge.net/ that you will install into your wine "windows"?但也许您正在寻找类似http://gnuwin32.sourceforge.net/ 之类的东西,您将安装到您的葡萄酒“窗口”中? Or the already mentioned cygwin.或者已经提到的cygwin。

for me the first solution I found on this site worked - associating an extension with winebrowser, and default gnome file viewer launches from wine when clicking on a file in wine explorer (or in other windows applications).对我来说,我在这个网站上找到的第一个解决方案有效 - 将扩展与 winebrowser 相关联,并且当单击 wine Explorer(或其他 Windows 应用程序)中的文件时,默认的 gnome 文件查看器从 wine 启动。

Previous solution with shell scripts , which worked in wine 1.4, does not work with wine 1.6 .以前在 wine 1.4中工作的shell scripts 解决方案不适用于 wine 1.6

However, the problem I noticed is that names in Windows encoding are not converted to Linux locale, preventing this to work with eg Russian directory names但是,我注意到的问题是 Windows 编码中的名称不会转换为 Linux 区域设置,从而阻止它与例如俄语目录名称一起使用

The shell script that was listed on WineHQ FAQ can be slightly modified, eg like this: WineHQ 常见问题解答列出的 shell 脚本可以稍作修改,例如:

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

The rest works just as described in the FAQ.其余的工作就像常见问题解答中描述的那样。

I love the Far Commander , which does run under wine , so I set up these two scripts:我喜欢Far Commander ,它确实在wine下运行,所以我设置了这两个脚本:

  1. To launch Linux applications from windows从 Windows 启动 Linux 应用程序

C:\\windows\\xt.bat C:\\windows\\xt.bat

start /unix /usr/bin/xterm -e %*
  1. To open files in Linux from the wine environment (Far):从 wine 环境 (Far) 在 Linux 中打开文件:

C:\\windows\\xdg.bat C:\\windows\\xdg.bat

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

/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)

Now I can type on the Far command line:现在我可以在 Far 命令行上输入:

xt top

xdg SomeDocument.PDF xdg SomeDocument.PDF

and get results in the Linux environment.并在 Linux 环境中得到结果。

Edit: user1182474's comment is correct;编辑:user1182474 的评论是正确的; Wine doesn't isolate the programs it runs. Wine 不会隔离它运行的程序。 (It tries to hide it, but not very thoroughly.) I totally failed at using Google. (它试图隐藏它,但不是很彻底。)我完全没有使用谷歌。 Psen's comment below is more correct, and references the FAQ.下面 Psen 的评论更正确,并参考了常见问题解答。 (Note that, for that to work, you may need to have the program's directory available through a Wine drive mapping. Or, see Anonymous Replier's answer.) (请注意,要使其正常工作,您可能需要通过 Wine 驱动器映射提供程序目录。或者,请参阅匿名回复者的回答。)

== Old Answer == == 旧答案 ==

Wine isolates the programs it runs. Wine 隔离它运行的程序。 The applications are, if all works as intended, presented with an environment indistinguishable from Windows.如果所有应用程序都按预期运行,那么这些应用程序将呈现与 Windows 无法区分的环境。 Unfortunately for your purposes, that means that you can't access the features of the host OS (Linux).不幸的是,这意味着您无法访问主机操作系统 (Linux) 的功能。 I mean, you could patch Wine to do that, but I get the impression that it would be more work than it's worth.我的意思是,你可以修补 Wine 来做到这一点,但我的印象是它会比它的价值更多的工作。

There is hope!还有希望! Cygwin is a Unix-like environment for Windows. Cygwin 是用于 Windows 的类 Unix 环境。 You could install Cygwin in Wine, and use Cygwin to run your shell script.您可以在 Wine 中安装 Cygwin,并使用 Cygwin 运行您的 shell 脚本。 (Apparently, installing with 'winetricks cygwin' is easiest) Invoke Cygwin's bash shell (inside some Wine program) like this: (显然,使用 'winetricks cygwin' 安装是最简单的)像这样调用 Cygwin 的 bash shell(在一些 Wine 程序中):

c:\cygwin\bin\bash  myscript

Of course, change c:\\cygwin to wherever you install it.当然,将 c:\\cygwin 更改为您安装它的任何位置。

Use SSH if you need to wait for the command to complete and get it's output.如果您需要等待命令完成并获取其输出,请使用 SSH。 Otherwise (if you need only to start it) any of these methods will work:否则(如果您只需要启动它)任何这些方法都可以工作:

The core problem is that CreateProcess returns zero PID and handle , so you can't wait for the child process completion and get it's exit code.核心问题是 CreateProcess 返回零 PID 和 handle ,因此您不能等待子进程完成并获取它的退出代码。

I've also tried standard pipes redirection with no luck.我也尝试过标准管道重定向,但没有成功。 The output of Linux child process is lost, pipes are empty. Linux 子进程的输出丢失,管道为空。

So, with CreateProcess and friends you have to use some kind of trigger files , which looks not too beautiful.所以,和 CreateProcess 和朋友一起,你必须使用某种触发器文件,看起来不太漂亮。 Like I said, we're going to use SSH instead.就像我说的,我们将改用 SSH。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM