2

I am trying to write a script in Python which opens wine and then sends code to the wine terminal to open a .exe program. The .exe program is also command driven.

I can open wine, but I can't get any further:

import shlex, subprocess

line = "/usr/bin/open -n -a /Applications/Wine\ Stable.app"
line2 = '''cd /Applications/application/ && wine application.exe /h1 
/k0 Z:/Users/myname/Desktop/File.TXT''' 
line = shlex.split(line)
p1 = subprocess.Popen(line)
p1.stdin.write(line2.encode())

The above doesn't work, wine doesn't seem to receive line2, although

/usr/bin/open -n -a /Applications/Wine\ Stable.app

by itself is fine (it opens Wine but nothing else.)

I'm pretty confused about what the next step should be. I would like to avoid additional dependencies if possible, because it seems simple.

  • ``shlex`` doesn't seem to keep new line chars, you'll need to deliminate the commands in the shell some how (as they are now all on one line). I would suggest using `&&` between the commands. – unDeadHerbs Oct 26 '17 at 22:56
  • that's a start, thanks for noticing that, however it still doesn't seem to work, even subbing line for '''/usr/bin/open -n -a /Applications/Wine\ Stable.app && cd /Applications/application/ ''' doesn't even open wine, whereas '''/usr/bin/open -n -a /Applications/Wine\ Stable.app''' will – dlozanothornton Oct 26 '17 at 23:01
  • Does the `Wine Stable.app` return when you call it or block the terminal? If it's blocking then the other commands won't run until it's done. – unDeadHerbs Oct 26 '17 at 23:02
  • how can I tell and how can I resolve the issue if it's blocking? – dlozanothornton Oct 26 '17 at 23:08
  • Try running the same command in a normal terminal and see if the terminal keeps working while the app is open or waits for it to close. If the program is blocking the terminal you can either have two calls to ``subprocess.Popen`` or you can use a single ``&`` rather than a double ``&&`` to fork the program into the background. – unDeadHerbs Oct 26 '17 at 23:10
  • terminal keeps working after wine is opened, but also -one point that might need clarifying- I am opening wine from the terminal, but every command afterwards should be sent to the wine terminal. This probably means I need two processes, but how do I address wine after I've opened it? This is my main issue. – dlozanothornton Oct 26 '17 at 23:17
  • In that case you don't want to give the other lines to the starting terminal but rather to the ``stdin`` of ``p1``. https://docs.python.org/3/library/subprocess.html#subprocess.Popen.stdin – unDeadHerbs Oct 26 '17 at 23:22
  • I've added `line2 = '''cd /Applications/application/ && wine application.exe /h1 /k0 Z:/Users/myname/Desktop/File.TXT''' p1.stdin.write(line2.encode()) after the code, still no dice – dlozanothornton Oct 26 '17 at 23:30
  • Can you update the question to match the current state of the problem? (Also use the backtick ` to make code in comments (it's below the ~ on US keyboards)). – unDeadHerbs Oct 26 '17 at 23:32
  • updated the question – dlozanothornton Oct 26 '17 at 23:41
  • I haven't used wine in a while or a mac, is ``Wine Stable.app`` a new window that needs typing in? – unDeadHerbs Oct 26 '17 at 23:45
  • yes, it is essentially its own terminal window – dlozanothornton Oct 26 '17 at 23:47
  • You'll need to look at it's documentation to see how to give it parameters then (as it's not waiting on stdin). See if it has a command line mode or can be passes a script file. – unDeadHerbs Oct 26 '17 at 23:49
  • https://wiki.winehq.org/MacOS_FAQ#How_to_create_shortcut.2C_launcher.2C_or_.app_to_start_a_given_.exe.3F this is as far as I've gotten, but I'm totally stumped from here. I could alter the code to run the applescript potentially. – dlozanothornton Oct 27 '17 at 00:31

1 Answers1

1

The following has worked for me in many cases (on Linux):

import subprocess

command = 'echo "echo foo && echo bar" | wine cmd > std_out.txt 2> std_error.txt &'
subprocess.Popen(command, shell = True)

(I believe wine is also available as a command on MacOS, just like that. Please correct me if I am wrong.)

The command fires up a Windows/DOS-like shell (wine cmd). You can actually type wine cmd into your Linux shell and hit enter - you'll find yourself in a DOS shell. The next step is to get commands into the DOS shell. I do this by piping them into it as a string. In my example, I run two commands: echo foo and echo bar. The initial echo writes the command string to stdout, the following | opens a pipe and forwards the string into the DOS shell.

Besides, once you send commands to the DOS shell, keep in mind that it expects Windows paths (when you change directories etc). I.e. you must translate your Unix paths into Windows paths before you send them into the DOS shell. You can automatically convert your path on a command line like this ...

winepath -w /home/ 2> /dev/null

... resulting in Z:\home\ (for example). Alternatively, the following Python snipped will do the same for you:

def convert_unix_path_to_windows_path(in_path):
    cmd = ['winepath', '-w', in_path]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (out, err) = proc.communicate()
    return out.decode('utf-8').strip()
s-m-e
  • 3,433
  • 2
  • 34
  • 71