first time posting in StackOverflow. :D I need my software to add a couple of things in the registry.
My program will use
Process.Star
In addition to the answers already provided, you can accomplish this by calling the command line programs "ASSOC" and "FTYPE". FTYPE associates a file type with a program. ASSOC associates a file extension with the file type specified through FTYPE. For example:
FTYPE SMCFile="C:\some_path\SMCProgram.exe" -some_option %1 %*
ASSOC .smc=SMCFile
This will make the necessary entries in the registry. For more information, type ASSOC /?
or FTYPE /?
at the command prompt.
Using Python:
EXT, EXT_TYPE = ".xyz", "XYZ file"
EXE_PATH = r"path\to\my\exe"
# %L is the long (full path) version of path
extCmd = '"%s" "%%L" %%*' % EXE_PATH
# Using assoc and ftype easier than editing registry!
assert os.system('assoc %s=%s' % (EXT, EXT_TYPE))==0
assert os.system('ftype %s=%s' % (EXT_TYPE, extCmd))==0
Associating an icon with the extension type:
import _winreg
try:
ext = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, EXT_TYPE)
_winreg.SetValue(ext, "DefaultIcon", _winreg.REG_SZ, ICON_PATH)
_winreg.CloseKey(ext)
except WindowsError:
print "Error associating icon"
Register the extension as an executable type (i.e. PATHEXT):
try:
key = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
reg = _winreg.ConnectRegistry( None, _winreg.HKEY_LOCAL_MACHINE )
# get current value
ext = _winreg.OpenKey(reg, key)
pathext = _winreg.QueryValueEx(ext, 'PATHEXT')[0]
if not EXT in pathext:
_winreg.CloseKey(ext)
# modify the current value
ext = _winreg.OpenKey(reg, key, 0, _winreg.KEY_ALL_ACCESS)
pathext += ';' + EXT
_winreg.SetValueEx(ext, 'PATHEXT', 0, _winreg.REG_SZ, pathext)
_winreg.CloseKey(ext)
_winreg.CloseKey(reg)
except WindowsError:
print "Error adding to PATHEXT"
Additionally, to get PATHEXT recognised without logging in again you can update the environment: (thanks to Enthought for this)
def refreshEnvironment():
HWND_BROADCAST = 0xFFFF
WM_SETTINGCHANGE = 0x001A
SMTO_ABORTIFHUNG = 0x0002
sParam = "Environment"
import win32gui
res1, res2 = win32gui.SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, sParam, SMTO_ABORTIFHUNG, 100)
Use the Registry class in Microsoft.Win32.
Specifically, you want the ClassesRoot property of Registry
to access the HKEY_CLASSES_ROOT key (cf. Understanding MS Windows File Associations and HKEY_CLASSES_ROOT: Core Services).
using Microsoft.Win32;
Registry
.ClassesRoot
.CreateSubKey(".smc")
.SetValue("", "SMC", RegistryValueKind.String);
Registry
.ClassesRoot
.CreateSubKey("SMC\shell\open\command")
.SetValue("", "SMCProcessor \"%1\"", RegistryValueKind.String);
Replace "SMCProcessor \"%1\""
with the command-line path and argument specification for the program that you wish to associate with files with extension .smc
.
But, instead of messing with the registry, why not just say
Process.Start("SMCProcessor blblabla.smc");
If you are planning on providing an installer for your application, simply use the file association feature available in whatever installer framework you choose to use - even the Visual Studio setup project knows how to do this.
To alter file type associations directly from your code, I believe you have to look into HKEY_CLASSES_ROOT
and find/create a key with the extension you want to bind to (ie ".pdf"). Within this key, the default value is a string containing a reference to another key within HKEY_CLASSES_ROOT
. Go follow that pointer, expand/create the shell
subkey and add/change your commands here. Look around this area with regedit
to get the fealing of how it looks.
I have some C# code in a pet project of mine, which looks up the binding for PDF files and adds an extra option to their context menus. Feel free to have a look.