first time posting in StackOverflow. :D
I need my software to add a couple of things in the registry.
My program will use
Process.Start(@"blblabla.smc");
to launch a file, but the problem is that most likely the user will not have a program set as default application for the particular file extension.
How can I add file associations to the WindowsRegistry?
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.
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");
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)
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.