UKnoHowWeDo
UKnoHowWeDo

Reputation: 373

Execute Shell Commands from Program running in WINE

I have a windows program running on Linux using WINE.

How can I call Linux shell commands from the windows program?

Upvotes: 25

Views: 42511

Answers (10)

Aleksandr
Aleksandr

Reputation: 349

Use SSH if you need to wait for the command to complete and get it's output. 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.

I've also tried standard pipes redirection with no luck. The output of Linux child process is lost, pipes are empty.

So, with CreateProcess and friends you have to use some kind of trigger files, which looks not too beautiful. Like I said, we're going to use SSH instead.

Upvotes: 0

ruvim
ruvim

Reputation: 8564

How to call a Linux program from a Wine program — five points in terms of API.

1. Proper 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.

2. Path to executable

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.

3. Executable format

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.

4. No waiting

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

5. Difference in pipes redirection

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.

Upvotes: 6

MKaama
MKaama

Reputation: 1939

I love the Far Commander, which does run under wine, so I set up these two scripts:

  1. To launch Linux applications from windows

C:\windows\xt.bat

start /unix /usr/bin/xterm -e %*
  1. To open files in Linux from the wine environment (Far):

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.

Upvotes: 1

Psen
Psen

Reputation: 119

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.

Upvotes: 11

adrianer
adrianer

Reputation: 171

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!

Upvotes: 17

Kos Ivantsov
Kos Ivantsov

Reputation: 1

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.

Upvotes: 0

Eugene
Eugene

Reputation: 111

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

Upvotes: 2

Daniel Ralston
Daniel Ralston

Reputation: 2280

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.

Upvotes: 0

David L.
David L.

Reputation: 3290

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.

Upvotes: 2

Anonymous Replier
Anonymous Replier

Reputation: 41

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.

Upvotes: 4

Related Questions