Enhanced robustness at startup.
[wine.git] / tools / winelauncher.in
blobf4e5590b33150a4ebc309efd076cdb31cb3bb894
1 #!/bin/sh
2 #------------------------------------------------------------------------------
3 # Winelauncher
4 # This shell script attempts to intelligently manage the process
5 # of launching a program with Wine. It adds some level of
6 # visual feedback to an end user.
7 #
8 # Usage:
9 # winelauncher [options] "<windows program> [program arguments]"
11 # This script is meant to be installed to /usr/bin/wine, and
12 # to be used to invoke a Windows executable.
13 # The options are passed through directly to Wine, and are
14 # documented in the Wine man page.
16 # Copyright (c) 2000 by Jeremy White for CodeWeavers
18 #------------------------------------------------------------------------------
20 #------------------------------------------------------------------------------
21 # Primary configuration area - change this if you installed Wine to
22 # a location other than @prefix@
23 #------------------------------------------------------------------------------
24 prefix=@prefix@
26 #------------------------------------------------------------------------------
27 # Secondary configuration area; change these at your own risk.
28 #------------------------------------------------------------------------------
29 exec_prefix=@exec_prefix@
30 WINEBIN=@bindir@
31 WINELIB=@libdir@
32 WINESERVER=
33 WINELIBDLLS=@libdir@
35 #------------------------------------------------------------------------------
36 # Establish Color Scheme
37 #------------------------------------------------------------------------------
38 COLOR=' -xrm *.Command.background:darkgrey
39 -xrm *.Command.foreground:black
40 -xrm *.Text.background:black
41 -xrm *.Text.foreground:green
42 -xrm *.Form.background:grey
43 -xrm *.Form.foreground:green
44 -xrm *.foreground:green
45 -xrm *.background:black'
48 #------------------------------------------------------------------------------
49 # Locate either xmessage or gmessage, if we can.
50 #------------------------------------------------------------------------------
51 type xmessage >/dev/null 2>/dev/null
52 if [ $? -ne 0 ] ; then
53 echo "
54 Warning:
55 The Wine launcher is unable to find xmessage.
57 This launcher script relies heavily on finding this tool,
58 and without it, it will behave poorly.
60 Most Linux distributions have one or the other of these
61 tools.
63 We strongly recommend that you use your distributions
64 software methods to locate xmessage."
66 else
67 XMESSAGE="xmessage $COLOR"
71 #------------------------------------------------------------------------------
72 # We're going to do a lot of fancy footwork below.
73 # Before we get started, it would be nice to know the argv0,
74 # of the actual script we're running (and lets remove at least
75 # one level of symlinking).
76 #------------------------------------------------------------------------------
77 argv0_path=`which $0`
78 if [ -z $argv0_path ] ; then
79 argv0_path=$0
82 real_name=`find $argv0_path -type l -printf "%l\n"`
83 if [ ! $real_name ]; then
84 real_name=$argv0_path
85 elif [ ! -x $real_name ]; then
86 real_name=`find $argv0_path -printf "%h\n"`/$real_name
89 argv0_dir=`find $real_name -printf "%h\n"`
91 if [ -z $argv0_dir ] ; then
92 argv0_dir=.
95 #------------------------------------------------------------------------------
96 # Okay, now all that junk above was established at configure time.
97 # However, if this is an RPM install, they may have chosen
98 # to relocate this installation. If so, that stuff above
99 # is all broken and we should rejigger it.
100 #------------------------------------------------------------------------------
101 WINE_BIN_NAME=wine.bin
102 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
103 WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
106 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
107 WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
110 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
111 WINE_BIN_NAME=wine
112 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
113 WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
116 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
117 WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -1`
121 if [ ! -r $WINELIB/libwine.so ] ; then
122 WINELIB=`find $argv0_dir -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -1`
125 if [ ! -r $WINELIB/libwine.so ] ; then
126 WINELIB=`find $argv0_dir/../ -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -1`
129 if [ -x $WINEBIN/wineserver ] ; then
130 WINESERVER=$WINEBIN/wineserver
133 #------------------------------------------------------------------------------
134 # Hey, if we built Wine from source, let's add a little extra fun to
135 # mix it up a bit
136 #------------------------------------------------------------------------------
137 if [ -x $WINEBIN/server/wineserver ] ; then
138 WINESERVER=$WINEBIN/server/wineserver
141 if [ -r $WINELIB/dlls/libntdll.so ] ; then
142 WINELIBDLLS=$WINELIB/dlls
146 #------------------------------------------------------------------------------
147 # Okay, set the paths and move on.
148 #------------------------------------------------------------------------------
149 export LD_LIBRARY_PATH=$WINELIB:$WINELIBDLLS:$LD_LIBRARY_PATH
150 export PATH=$WINEBIN:$PATH
151 export WINEDLLPATH=$WINELIBDLLS
152 export WINELOADER=$WINEBIN/$WINE_BIN_NAME
154 info_flag=~/.wine/.no_prelaunch_window_flag
155 debug_flag=~/.wine/.no_debug_window_flag
156 debug_options="-debugmsg warn+all"
158 if [ -f $info_flag ] ; then
159 use_info_message=0
160 else
161 use_info_message=1
164 if [ -f $debug_flag ] ; then
165 use_debug_message=0
166 else
167 use_debug_message=1
171 #------------------------------------------------------------------------------
172 # Handle winelib apps going through here
173 #------------------------------------------------------------------------------
174 winelib=0
175 if [ -f $argv0_path.so ] ; then
176 winelib=1
177 export WINEPRELOAD=$argv0_path.so
181 #------------------------------------------------------------------------------
182 # No arguments? Help 'em out
183 #------------------------------------------------------------------------------
184 always_see_output=0
185 no_args=0
186 if [ $# -eq 0 ] ; then
187 no_args=1
190 if [ $# -eq 1 -a "$1" = "" ] ; then
191 no_args=1
194 if [ $winelib -eq 1 ] ; then
195 no_args=0
198 if [ $no_args -eq 1 ] ; then
199 echo "Wine called with no arguments."
200 echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
201 $XMESSAGE -buttons " Okay ":0," See the Wine Usage Statement ":1," Configure Wine ":2 \
202 -title "Welcome to Wine" \
205 You have started Wine without specifying any arguments.
207 Wine requires a least one argument - the name of the Windows
208 application you would like to run.
210 If you have launched this through the KDE menu system,
211 you can use the KDE file browser to select a Windows
212 exectuable and then click on it to launch Wine with
213 that application.
215 You can similarly use the GNOME file manager to
216 select a Windows executable and double click on it.
218 If you would like to see the command line arguments
219 for Wine, select the second option, below.
222 welcome_rc=$?
223 if [ $welcome_rc -eq 0 ] ; then
224 exit
227 if [ $welcome_rc -eq 2 ] ; then
228 which winesetup
229 if [ $? -eq 0 ] ; then
230 winesetup
231 else
232 if [ -x /opt/wine/bin/winesetup ] ; then
233 /opt/wine/bin/winesetup
234 else
235 $XMESSAGE -title "Error" "Error: Unable to find winesetup in your PATH or in /opt/wine/bin"
238 exit
241 use_info_message=0
242 always_see_output=1
245 #------------------------------------------------------------------------------
246 # No config file? Offer to help 'em out...
247 #------------------------------------------------------------------------------
248 conf=0
250 while [ $conf -eq 0 ] ; do
252 if [ -f ~/.winerc ] ; then
253 conf=1
255 if [ -f ~/.wine/config ] ; then
256 conf=2
258 if [ -f /etc/wine.conf ] ; then
259 conf=3
262 if [ $conf -ne 0 ] ; then
263 break;
266 echo "No configuration file detected."
267 $XMESSAGE -buttons " Cancel ":0," Proceed ":1," Configure Wine ":2 \
268 -title "Welcome to Wine" \
271 You have started Wine but we cannot find a Wine
272 configuration file.
274 This is normal if you have never run Wine before.
275 If this is the case, select the 'Configure Wine'
276 option, below, to create a configuration file.
279 init_rc=$?
280 if [ $init_rc -eq 0 ] ; then
281 exit
284 if [ $init_rc -eq 1 ] ; then
285 break
288 if [ $init_rc -eq 2 ] ; then
289 which winesetup
290 if [ $? -eq 0 ] ; then
291 winesetup
292 else
293 if [ -x /opt/wine/bin/winesetup ] ; then
294 /opt/wine/bin/winesetup
295 else
296 $XMESSAGE -title "Error" "Error: Unable to find winesetup in your PATH or in /opt/wine/bin"
301 done
303 #------------------------------------------------------------------------------
304 # Optionally Warn the user we're going to be launching Wine...
305 #------------------------------------------------------------------------------
306 if [ $use_info_message -ne 0 ] ; then
307 echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
308 $XMESSAGE -timeout 30 -buttons " Dismiss ":0," Never display this message again ":3 \
309 -title "Wine Launch Window" \
310 "Invoking $WINEBIN/$WINE_BIN_NAME $@ ...
312 This dialog box is a temporary status dialog to let you know
313 that Wine is attempting to launch your application.
315 Since Wine is still very much in a development stage, many
316 applications will fail silently. This dialog box is your indication
317 that we're *trying* to run your application.
319 This dialog box will automatically disappear after 30 seconds,
320 or after your application finishes.
322 You can permanently disable this dialog by selecting the option below.
324 info_message_pid=$!
327 #------------------------------------------------------------------------------
328 # Here's a little function to clean up after that dialog...
329 #------------------------------------------------------------------------------
330 clean_up_info_message ()
332 if [ $use_info_message -ne 0 ] ; then
334 #------------------------------------------------------------------------------
335 # Okay, make sure that the notice window is dead (and kill it if it ain't)
336 #------------------------------------------------------------------------------
337 ps $info_message_pid >/dev/null 2>&1
338 if [ $? -ne 0 ] ; then
339 wait $info_message_pid
340 info_return=$?
341 else
342 info_return=0
343 kill $info_message_pid
346 #------------------------------------------------------------------------------
347 # If they didn't like the warning window, turn it off
348 #------------------------------------------------------------------------------
349 if [ $info_return -eq 3 ] ; then
350 $XMESSAGE -title "Wine Prelaunch Control" \
351 "Wine will now disable the prelaunch Window you just saw.
352 You will no longer be notified when Wine is attempting
353 to start a Windows application.
355 You can reenable this Window by removing the $info_flag file." -buttons " Okay ":0," Cancel ":1
356 if [ $? -eq 0 ] ; then
357 touch $info_flag
362 use_info_message=0
364 #------------------------------------------------------------------------------
365 # Generate a temporary log file name
366 #------------------------------------------------------------------------------
367 use_log_name=0
368 log_name=`mktemp /tmp/wine.log.XXXXXX`
369 if [ $? -eq 0 ] ; then
370 which tail >/dev/null 2>&1
371 if [ $? -eq 0 ]; then
372 use_log_name=1
376 #------------------------------------------------------------------------------
377 # Okay, really launch Wine...
378 #------------------------------------------------------------------------------
379 if [ $use_log_name -ne 0 ] ; then
380 #------------------------------------------------------------------------------
381 # Okay, we bend over backwards to run Wine, get that status,
382 # but still display its output to the screen.
383 # The obvious thing to do is to run wine and pipe output to tee,
384 # but then I can't find a way to get the return code of wine;
385 # I only get the return code of tee.
386 #------------------------------------------------------------------------------
387 $WINEBIN/$WINE_BIN_NAME "$@" >$log_name 2>&1 &
388 wine_pid=$!
390 tail -f $log_name &
391 tail_pid=$!
393 wait $wine_pid
394 wine_return=$?
396 kill $tail_pid
397 else
398 $WINEBIN/$WINE_BIN_NAME "$@"
399 wine_return=$?
402 #------------------------------------------------------------------------------
403 # Test the return code, and see if it fails
404 #------------------------------------------------------------------------------
405 if [ $always_see_output -eq 0 -a $wine_return -eq 0 ] ; then
406 echo "Wine exited with a successful status"
407 if [ $use_log_name -ne 0 ] ; then
408 rm -f $log_name
410 else
411 if [ $always_see_output -eq 0 ] ; then
412 echo "Wine failed with return code $wine_return"
415 #------------------------------------------------------------------------------
416 # Gracefully display a debug message if they like...
417 #------------------------------------------------------------------------------
418 while [ $use_debug_message -gt 0 ] ; do
420 #------------------------------------------------------------------------------
421 # Build up the menu of choices they can make...
422 #------------------------------------------------------------------------------
423 BUTTONS=' Okay :0'
424 if [ $use_log_name -ne 0 ] ; then
425 BUTTONS="$BUTTONS"', View Log :1'
428 BUTTONS="$BUTTONS"', Debug :2'
429 BUTTONS="$BUTTONS"', Configure :4'
430 BUTTONS="$BUTTONS"', Disable :3'
432 #------------------------------------------------------------------------------
433 # Build an error message
434 #------------------------------------------------------------------------------
435 MESSAGE="
436 Wine has exited with a failure status of $wine_return.
438 Wine is still development software, so there can be many
439 explanations for this problem.
441 You can choose to run Wine again with a higher level
442 of debug messages (the debug option, below).
444 You can attempt to reconfigure Wine to make it work better.
445 Note that one change you can make that will dramatically
446 effect Wine's behaviour is to change whether or not
447 Wine uses a true Windows partition, mounted under Linux,
448 or whether it uses an empty Windows directory.
449 The Wine Configuration program can assist you in making
450 those changes (select Configure, below, for more).
452 You can disable this message entirely by selecting the
453 Disable option below."
455 if [ $always_see_output -ne 0 -a $wine_return -eq 0 ] ; then
456 MESSAGE="
457 Wine has exited with a failure status of $wine_return.
459 You can disable this message entirely by selecting the
460 Disable option below."
464 if [ $use_log_name -ne 0 ] ; then
465 MESSAGE="$MESSAGE
467 Wine has captured a log of the Wine output in the file $log_name.
468 You may view this file by selecting View Log, below."
471 #------------------------------------------------------------------------------
472 # Display the message
473 #------------------------------------------------------------------------------
474 $XMESSAGE -title "Wine Finished With Error" -buttons "$BUTTONS" "$MESSAGE"
475 debug_return=$?
477 #------------------------------------------------------------------------------
478 # Dismiss the other window...
479 #------------------------------------------------------------------------------
480 clean_up_info_message
482 #------------------------------------------------------------------------------
483 # Process a configure instruction
484 #------------------------------------------------------------------------------
485 if [ $debug_return -eq 4 ] ; then
486 which winesetup
487 if [ $? -eq 0 ] ; then
488 winesetup
489 else
490 if [ -x /opt/wine/bin/winesetup ] ; then
491 /opt/wine/bin/winesetup
492 else
493 $XMESSAGE -title "Error" "Error: Unable to find winesetup in your PATH or in /opt/wine/bin"
496 continue;
499 #------------------------------------------------------------------------------
500 # Process a view instruction
501 #------------------------------------------------------------------------------
502 if [ $debug_return -eq 1 ] ; then
503 $XMESSAGE -title "View Wine Log" -file $log_name -buttons " Okay ":0,"Delete $log_name":1
504 if [ $? -eq 1 ] ; then
505 echo "Deleting $log_name"
506 rm -f $log_name
507 use_log_name=0
509 else
510 use_debug_message=0
513 #------------------------------------------------------------------------------
514 # If they didn't like the warning window, turn it off
515 #------------------------------------------------------------------------------
516 if [ $debug_return -eq 3 ] ; then
517 $XMESSAGE -title "Wine Debug Log Control" \
518 "Wine will now disable the Wine debug output control window you just saw.
519 You will no longer be notified when Wine fails to start a
520 Windows application.
522 You can reenable this Window by removing the $debug_flag file." -buttons " Okay ":0," Cancel ":1
524 if [ $? -eq 0 ] ; then
525 touch $debug_flag
530 #------------------------------------------------------------------------------
531 # If they want to retry with debug, let 'em.
532 #------------------------------------------------------------------------------
533 if [ $debug_return -eq 2 ] ; then
534 echo "Rerunning $0 $debug_options $@"
535 exec $0 $debug_options $@
537 done
541 clean_up_info_message