19

I'm wondering how to open files in programs such as Notepad and Picture Viewer depending on the extension the file has. I'm using Python 3.3 on Windows.

I've done some research and people have mentioned a module named Image, but when I try and import this module I get an ImportError.

Here's what I have so far:

def openFile():
    fileName = listbox_1.get(ACTIVE)
    if fileName.endswith(".jpg"):
        fileName.open()

I will also have HTML and JSON files that I will need to open in Notepad.

APerson
  • 8,140
  • 8
  • 35
  • 49

3 Answers3

36

On Windows you could use os.startfile() to open a file using default application:

import os
os.startfile(filename)

There is no shutil.open() that would do it cross-platform. The close approximation is webbrowser.open():

import webbrowser
webbrowser.open(filename)

that might use automatically open command on OS X, os.startfile() on Windows, xdg-open or similar on Linux.

If you want to run a specific application then you could use subprocess module e.g., Popen() allows to start a program without waiting for it to complete:

import subprocess

p = subprocess.Popen(["notepad.exe", fileName])
# ... do other things while notepad is running
returncode = p.wait() # wait for notepad to exit

There are many ways to use the subprocess module to run programs e.g., subprocess.check_call(command) blocks until the command finishes and raises an exception if the command finishes with a nonzero exit code.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • only problem is that json files don't have a default application so that box would appear asking the user what program to open it in –  Feb 24 '13 at 18:39
  • @LWH91: I've added subprocess-based solution to run a program explicitly. – jfs Feb 24 '13 at 18:55
  • You write, "On windows you could [...]" Does `os.startfile` not work on Linux machines? – Toothpick Anemone Nov 09 '19 at 01:58
  • @ToothpickAnemone: yes, there is no `os.startfile` on Linux. Follow the link to `os.startfile()` docs in the answer (it says that the function is available only on Windows) – jfs Nov 10 '19 at 06:41
  • os.startfile is exactly what I was looking for! – Elyasaf755 Nov 14 '21 at 14:07
12

Use this to open any file with the default program:

import os
def openFile():
    fileName = listbox_1.get(ACTIVE)
    os.system("start " + fileName)

If you really want to use a certain program, such as notepad, you can do it like this:

import os
def openFile():
    fileName = listbox_1.get(ACTIVE)
    os.system("notepad.exe " + fileName)

Also if you need some if checks before opening the file, feel free to add them. This only shows you how to open the file.

  • 2
    `os.system()` will block the calling thread. Something out of the `subprocess` module might be more appropriate. – FatalError Feb 24 '13 at 17:37
  • I thin ill need to add the program name because files such as json that don't have a specific program to open will cause problems –  Feb 24 '13 at 17:39
  • @LWH91 I'd recommend adding a check if the file ends with `.json`, if it does, open the file with a custom program. Else use "start". –  Feb 24 '13 at 17:43
  • yeah was going to put in a double check for json and html then use else to open the rest –  Feb 24 '13 at 17:45
  • @MarkusMeskanen when i use your example code all that happens is a console windows pops up for a second then disappears –  Feb 24 '13 at 18:17
  • 4
    This appears to be windows only – Jonathan Oct 01 '15 at 02:06
6

Expanding on FatalError's suggestion with an example.

One additional benefit of using subprocessing rather than os.system is that it uses the same syntax cross-platform (os.system on Windows requires a "start" at the beginning, whereas OS X requires an "open". Not a huge deal, but one less thing to remember).

Opening a file with subprocess.call.

All you need to do to launch a program is call subprocess.call() and pass in a list of arguments where the first is the path to the program, and the rest are additional arguments that you want to supply to the program you're launching.

For instance, to launch Notepad.exe

import subprocess    

path_to_notepad = 'C:\\Windows\\System32\\notepad.exe'
path_to_file = 'C:\\Users\\Desktop\\hello.txt'

subprocess.call([path_to_notepad, path_to_file])

Passing multiple arguments and paths is equally as simple. Just add additional items to the list.


Launching with multiple arguments

This, for example, launches a JAR file using a specific copy of the Java runtime environment.

import subprocess
import os

current_path = os.getcwd()
subprocess.call([current_path + '/contents/home/bin/java', # Param 1
                    '-jar', #Param2
                    current_path + '/Whoo.jar']) #param3

Argument 1 targets the program I want to launch. Argument2 supplies an argument to that program telling it that it's going to run a JAR, and finally Argument3 tells the target program where to find the file to open.

Tim Skov Jacobsen
  • 3,583
  • 4
  • 26
  • 23
Zack Yoshyaro
  • 2,056
  • 6
  • 24
  • 46