40

I want to run a program on several platforms (including Mac OS), so I try to keep it as platform independent as possible. I use Windows myself, and I have a line os.startfile(file). That works for me, but not on other platforms (I read in the documentation, I haven't tested for myself).

Is there an equivalent that works for all platforms?

By the way, the file is a .wav file, but I want users to be able to use their standard media player, so they can pause/rewind the file. That's why I use os.startfile(). I might be able to work with libraries that also allow playing/pausing/rewinding media files.

Lewistrick
  • 2,649
  • 6
  • 31
  • 42
  • Try : http://www.pygame.org/project-Python+Media+Player-185-.html – Ashwini Chaudhary Jun 26 '13 at 10:12
  • related: [Start Another Program From Python >Separately<](http://stackoverflow.com/q/13078071/4279) – jfs Feb 24 '14 at 12:19
  • I just felt this was an excellent time to advertise my package, pyquark, which has an OS-independent way of doing this. You can install it with `pip install` pyquark and then `import pyquark pyquark.filestart('file.file')` – CodeWizard777 Apr 26 '22 at 21:42

4 Answers4

79

It appears that a cross-platform file opening module does not yet exist, but you can rely on existing infrastructure of the popular systems. This snippet covers Windows, MacOS and Unix-like systems (Linux, FreeBSD, Solaris...):

import os, sys, subprocess

def open_file(filename):
    if sys.platform == "win32":
        os.startfile(filename)
    else:
        opener = "open" if sys.platform == "darwin" else "xdg-open"
        subprocess.call([opener, filename])
goji
  • 6,911
  • 3
  • 42
  • 59
user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • Thanks, I hope this works. I will accept your answer as soon as I can test the program on other platforms. – Lewistrick Jun 26 '13 at 15:34
  • For Windows, the quotations around the filename should be omitted. Does this matter for other platforms? – Lewistrick Jun 26 '13 at 15:37
  • @Lewistrick Without the quotes files with spaces in file or directory name won't work, which is always a bug waiting to happen. I've now edited the answer to simply use `os.startfile` on Win32, and open/xdg-open elsewhere. Now that Windows is handled separately, the code can use `subprocess.call` to handle file names with spaces or special characters. (On Windows `start` is part of `cmd`, so `subprocess.call` without `shell=True` wouldn't work.) – user4815162342 Jun 26 '13 at 16:18
  • Thanks! Can I do a similar thing for deleting files? For both Windows and Unix I can use `os.remove()`, and if I'm right, MacOS uses `rm` for removing. Can I use `subprocess.call(["rm", filename])` in MacOS? – Lewistrick Jun 27 '13 at 07:42
  • 2
    @Lewistrick `os.remove` will work on all three OS-es, so I suggest that you stick to that. MacOS is in most lower-level things close to a POSIX system. – user4815162342 Jun 27 '13 at 08:52
  • I should've looked that up. It says somewhere else that MacOS counts as Unix when using `os.remove` :) – Lewistrick Jun 27 '13 at 08:56
  • @user4815162342: what happens if you run `python -mwebbrowser some.wav` on your system? – jfs Feb 24 '14 at 12:40
  • @user4815162342: I infer that it works on your system. Thank you. – jfs Feb 24 '14 at 13:52
  • @user4815162342 This is a good answer, but not great, because it emits a warning in syntax checkers like pylint: `Module 'os' has no 'startfile' member (no-member)` – Babken Vardanyan Aug 09 '14 at 07:35
  • @BabkenVardanyan That should be reported as a bug to the syntax checker maintainers, since `startfile` is a [documented member of `os`](https://docs.python.org/2/library/os.html#os.startfile) on Windows. – user4815162342 Aug 09 '14 at 10:48
  • @user4815162342 It is, on Windows, but not on Unix, where the software might be developed and syntax-checked. Adding checks to syntax checkers whether a statement is invoked only on an execution path in case of a specific system would be too complicated I think. – Babken Vardanyan Aug 09 '14 at 10:53
  • @BabkenVardanyan My point is that the checker software has no place warning against the use of a documented function. It's a bug in the checker, not in the code that invokes `os.startfile`. – user4815162342 Aug 09 '14 at 13:06
  • Surprisingly, this is not in any library in Pypi (that I have seen) – jjmerelo May 01 '21 at 07:47
  • I just felt this was an excellent time to advert py package, pyquark, witch has a OS - independant way of doing this. You can install it with `pip install pyquark ` and then `import pyquark pyquark.filestart('file.file')` – CodeWizard777 Apr 26 '22 at 21:42
3

Just use webbrowser.open(filename). it can call os.startfile(), open, xdg-open where appropriate.

Beware, there is a scary text in the docs:

Note that on some platforms, trying to open a filename using this function, may work and start the operating system’s associated program. However, this is neither supported nor portable.

It works fine for me. Test it in your environment.

Look at webbrower's source code to see how much work needs to be done to be portable.

There is also an open issue on Python bug tracker -- Add shutil.open. "portable os.startfile()" interface turned out to be more complex than expected. You could try the submitted patches e.g., shutil.launch().

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 1
    This won't work on OS X. On both Python 2.7 and Python 3, this returns `True` but doesn't actually do anything. – Luke Taylor May 11 '16 at 22:10
  • @LukeTaylor I believe webbrowser uses `open` command on OS X. If it doesn't work for you then create a minimal code example and post it as a separate question. – jfs May 11 '16 at 22:15
  • It's not a big concern for me, I just wanted to let you know. – Luke Taylor May 11 '16 at 22:22
  • @LukeTaylor without a specific code example that reproduces the issue; it is not very useful. Is it hard to write: `python -m webbrowser my.wav` and describe what is happening, mention your OS, python versions. That is all. – jfs May 11 '16 at 22:25
0

It depend what you mean with platform independent. If your question is about how to open anything using the default action of the OS, for example, when you double click on some file to let the OS decide how to open it, then the simple answer is no.

However, to implement this functionality yourself, is very easy, but you need to use a few different methods to accommodate for different OS's. That said, the most forgiving method is to use os.system(WinPathWithArgs) as I have explained in this answer.

not2qubit
  • 14,531
  • 8
  • 95
  • 135
0

Try this:

import subprocess

subprocess.Popen(["open", 'directory'])
krmogi
  • 2,588
  • 1
  • 10
  • 26