I have a windows program running on Linux using WINE.
How can I call Linux shell commands from the windows program?
I have a windows program running on Linux using WINE.
How can I call Linux shell commands from the windows program?
Edit: user1182474's comment is correct; Wine doesn't isolate the programs it runs. (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. (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.)
== Old Answer ==
Wine isolates the programs it runs. The applications are, if all works as intended, presented with an environment indistinguishable from Windows. Unfortunately for your purposes, that means that you can't access the features of the host OS (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.
There is hope! Cygwin is a Unix-like environment for Windows. You could install Cygwin in Wine, and use Cygwin to run your shell script. (Apparently, installing with 'winetricks cygwin' is easiest) Invoke Cygwin's bash shell (inside some Wine program) like this:
c:\cygwin\bin\bash myscript
Of course, change c:\cygwin to wherever you install it.
Try this (runs Gnome calculator on my Linux Mint system):
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. 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?
So you should be able to write shell scripts and call them OK.
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):
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:
cmd /c start /unix /usr/bin/gedit
To test this, you can call directly on your Linux console this:
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!
Try (where yourprogram is the linux/unix program you want to execute in wine)
ln -s /path/to/yourprogram /path/to/wineprefix/drive_c/windows/system32/yourprogram
That is how I have gotten java working.
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).
Previous solution with shell scripts, which worked in wine 1.4, does not work with 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 e.g. Russian directory names
How to call a Linux program from a Wine program — five points in terms of API.
PATHEXT
In the new Wine versions (since 2.0.1 at least) it is need to add empty extension (i.e. just dot character: .
) into the list of executable file extensions in PATHEXT
environment variable. 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
):
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 .
item only.
See also: How do I launch native applications from a Windows application? in WineHQ FAQ; 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.
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.
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. I.e. /bin/bash
just works, but not bash
.
Another way is to alter PATH
environment variable in Wine accordingly, or to change the current directory.
Whenever a path contains non-ASCII characters — as argument of CreateProcessA
— the path should be in Wine locale and according to LANG
environment variable; 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. For CreateProcessW
the path should be in UTF-16 in any case.
Linux executables in shared object format cannot be executed from Wine. See: Executables vs Shared objects and How to execute shell scripts from 32-bit Wine on 64-bit Linux. 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. 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.
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).
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).
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. While in Windows these handles can be closed just after CreateProcess
function is completed. By MSDN these handles may be closed at once after passing (see CreateProcess function):
Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.
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. But not in the case of a child Windows process.
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"? Or the already mentioned cygwin.
The shell script that was listed on WineHQ FAQ can be slightly modified, eg like this:
#!/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:
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)
Now I can type on the Far command line:
xt top
xdg SomeDocument.PDF
and get results in the Linux environment.