1

So, I have written a python app that runs on system startup on Windows7/8/Vista/XP. The first time it is ran, I want it to associate a few file types/extensions with a certain program which is on the system. For the time being, I accomplish this like so:

import win32com.shell.shell as shell

def runAssoc():
    shell.ShellExecuteEx(
    lpVerb="runas",
    lpFile='c:\\Users\\myUser\\assoc.bat')

Problem is, when ran from startup this sometimes fails to work. I've read here that ShellExecuteEx does not output it's errors to the calling process, so i don't see what's going loose on that end, and also read on the articles given there that lpVerb="runas" is generally considered a bad practice.

My assoc.bat requires administrator approval as it is written the following way:

assoc .txt=myNotepad
assoc .hello=myNotepad
ftype myNotepad="C:\Windows\system32\notepad.exe" "%%1"

(Here I'm associating Microsoft's Notepad that comes with Windows to "txt" and "hello" extensions. That of course makes no sense but is a good example.)

I understand that Windows does not provide a command line tool that allows us to associate file extensions to programs for the current user only (which will do fine for what i'm trying to achieve).
On this article I read assoc effects an area of the registry used by every user account in your Windows installation, instead of HKEY_CURRENT_USER that could be written to without admin permissions.

I read another answer here suggesting to check sys.argv[-1] != "asadmin", but sys.argv seems to be an empty array every time my app runs.

1) Can I make sure ShellExecuteEx runs and prompts for admin privileges when required?

2) Maybe there's a way I can create a batch file that will associate these extensions to the current user only? Than, I won't need to use the 'runas' parameter which is supposedly the source of error.

A little side note: in actuallity I build this batch file 'programmatically' on the fly, but this is not discussed here as it is not really related to the issue.

Community
  • 1
  • 1
user1555863
  • 2,567
  • 6
  • 35
  • 50

1 Answers1

1

Probably the easiest thing to do would be to make a .reg file and execute that you can just write the registry keys you need directly in the reg file. Like for example:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\.hello]
@="txtfile"

You can obviously make the myNotepad type too. You can assoc and then use regedit to make the reg file (select key and rmb + export) You can tell window to install the reg silently if you use:

regedit -s your_reistration_file.reg

Now you can call the line above with the ShellExecuteEx. Please note the uer may not have rights to edit the registry with reg files.

You can also edit registry in python directly, here is an example of above see docs for winreg for more info:

import _winreg #just winreg in Python 3

key = _winreg.OpenKey(
    _winreg.HKEY_CURRENT_USER,
    r"Software\Classes"
    )

hello = _winreg.CreateKeyEx(key, ".hello")
_winreg.SetValue(hello, '', _winreg.REG_SZ, 'txtfile')
joojaa
  • 4,354
  • 1
  • 27
  • 45