15

I am trying to figure out how to make a python program open a file when a user right clicks on the file and selects "Open With". For example, I want a user to be able right click on a text file and to select my program so that my program can process the text file. Is the name of the text file passed into my program someway? Thanks.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
osdev0
  • 280
  • 4
  • 7
  • An answer to a similar question: [https://stackoverflow.com/a/73288976/19709641](https://stackoverflow.com/a/73288976/19709641) – coolcoder613 Aug 10 '22 at 00:05
  • An answer to a similar question [https://stackoverflow.com/a/73288976/19709641](https://stackoverflow.com/a/73288976/19709641) – coolcoder613 Aug 10 '22 at 00:06

4 Answers4

7

My approach is to use a redirect .bat file containing python someprogram.py %1. The %1 passes the file path into the python script which can be accessed with
from sys import argv argv[1]

Roy Cai
  • 166
  • 1
  • 3
3

The problem with this approach is that your .py file is not an executable; Windows will pass the text file as parameter to the .py file, but the .py file itself will not do anything, since it's not an executable file.

What you can do is compile your script with py2exe to get an actual executable, which you can actually specify in the "Open With..." screen (you could even register it as the default for any *.foo file). The path to the .foo file being passed should be sys.argv[1] in your script.

Giacomo Lacava
  • 1,784
  • 13
  • 25
  • py2exe is an overkill since it makes a program to a standalone exe which doesn't require python at all and it needs to be recompiled every time the program is changed (in case you develop it). There are exe wrappers in %python%\Scripts\ which just launch a python script with same name. Someone knows something about it? – Smit Johnth Mar 15 '15 at 05:34
2

First you will need to register your script to run with Python under a ProgId in the registry. At a minimum, you will need the open verb defined:

HKEY_CURRENT_USER\Software\Classes\MyApp.ext\
  (Default) = "Friendly Name"
  DefaultIcon\
    (Default) = "path to .ico file"
  shell\
    open\
      command\
        (Default) = 'path\python.exe "path\to\your\script.py" "%L"'

You can substitute HKEY_LOCAL_MACHINE if you are installing machine-wide.* There are also versioning conventions that you can probably ignore. The MSDN section on File Types has more detailed information.

The second step is to add your ProgId to the OpenWithProdIds key of the extension you want to appear in the list for:

HKEY_CURRENT_USER\Software\Classes\.ext\OpenWithProgIds
  MyApp.ext = None

The value of the key does not matter, as long as the name matches your ProgId exactly.


*Note that HKEY_CLASSES_ROOT is actually a fake key that 'contains' a union of both HKLM\Software\Classes and HKCU\Software\Classes; if you're writing to the registry, you should choose one of the actual keys. You don't need to elevate to install into HKEY_CURRENT_USER.

Zooba
  • 11,221
  • 3
  • 37
  • 40
  • I'll declare that I haven't tried this, since I don't particularly want to mess with my settings on this machine. MSDN suggests that a few other values need to be set but a quick look through my registry says they aren't needed. Definitely interested if this minimal solution works; go ahead and edit in any extra bits I've missed. – Zooba Jan 09 '12 at 08:43
  • 1
    This simply doesn't work; selecting the .py in the 'open with' menu still reports it is not a win32 application. – Anti Earth Jan 03 '13 at 11:10
  • I think this might work with 'Send To' but not with 'Open With'. – JeffUK Feb 10 '21 at 15:43
  • got it to work but the label in "Open with..." is "Python", not whatever I set there in the registry – Christoph Rackwitz Dec 16 '21 at 16:40
0

@roy cai's answer is right, it just needs some modifications.

According to here, the someprogram.bat should contain

start someprogram.py(w) %*

Just give your cmdline args to the bat file. The %* takes up all the cmdline args, according to here from here.

Great Owl
  • 23
  • 4