2222from winpython .py3compat import winreg
2323from winpython import utils
2424
25+ KEY_C = r"Software\Classes\%s"
26+ KEY_C0 = KEY_C % r"Python.%sFile\shell\%s"
27+ KEY_C1 = KEY_C0 + r"\command"
28+ KEY_I = KEY_C % r"Python.%sFile\DefaultIcon"
29+ KEY_D = KEY_C % r"Python.%sFile"
30+ EWI = "Edit with IDLE"
31+ EWS = "Edit with Spyder"
32+
33+
34+ def _get_shortcut_data (target , current = True ):
35+ wpgroup = utils .create_winpython_start_menu_folder (current = current )
36+ wpdir = osp .join (target , os .pardir )
37+ data = []
38+ for name in os .listdir (wpdir ):
39+ bname , ext = osp .splitext (name )
40+ if ext == '.exe' :
41+ data .append ( (osp .join (wpdir , name ),
42+ bname ,
43+ osp .join (wpgroup , bname )) )
44+ return data
45+
2546
2647def register (target , current = True ):
2748 """Register a Python distribution in Windows registry"""
2849 root = winreg .HKEY_CURRENT_USER if current else winreg .HKEY_LOCAL_MACHINE
2950
3051 # Extensions
31- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .py" ),
52+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .py" ),
3253 "" , 0 , winreg .REG_SZ , "Python.File" )
33- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .pyw" ),
54+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .pyw" ),
3455 "" , 0 , winreg .REG_SZ , "Python.NoConFile" )
35- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .pyc" ),
56+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .pyc" ),
3657 "" , 0 , winreg .REG_SZ , "Python.CompiledFile" )
37- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .pyo" ),
58+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .pyo" ),
3859 "" , 0 , winreg .REG_SZ , "Python.CompiledFile" )
3960
4061 # MIME types
41- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .py" ),
62+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .py" ),
4263 "Content Type" , 0 , winreg .REG_SZ , "text/plain" )
43- winreg .SetValueEx (winreg .CreateKey (root , r"Software\Classes\ .pyw" ),
64+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C % " .pyw" ),
4465 "Content Type" , 0 , winreg .REG_SZ , "text/plain" )
4566
4667 # Verbs
4768 python = osp .abspath (osp .join (target , 'python.exe' ))
4869 pythonw = osp .abspath (osp .join (target , 'pythonw.exe' ))
49- pat = r"Software\Classes\Python.%sFile\shell\%s\command"
50- winreg .SetValueEx (winreg .CreateKey (root , pat % ("" , "open" )),
70+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("" , "open" )),
5171 "" , 0 , winreg .REG_SZ , '"%s" "%%1" %%*' % python )
52- winreg .SetValueEx (winreg .CreateKey (root , pat % ("NoCon" , "open" )),
72+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("NoCon" , "open" )),
5373 "" , 0 , winreg .REG_SZ , '"%s" "%%1" %%*' % pythonw )
54- winreg .SetValueEx (winreg .CreateKey (root , pat % ("Compiled" , "open" )),
74+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("Compiled" , "open" )),
5575 "" , 0 , winreg .REG_SZ , '"%s" "%%1" %%*' % python )
56- ewi = "Edit with IDLE"
57- winreg .SetValueEx (winreg .CreateKey (root , pat % ("" , ewi )),
76+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("" , EWI )),
5877 "" , 0 , winreg .REG_SZ ,
5978 '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
6079 % (pythonw , target ))
61- winreg .SetValueEx (winreg .CreateKey (root , pat % ("NoCon" , ewi )),
80+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("NoCon" , EWI )),
6281 "" , 0 , winreg .REG_SZ ,
6382 '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
6483 % (pythonw , target ))
84+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("" , EWS )),
85+ "" , 0 , winreg .REG_SZ ,
86+ '"%s" "%s\Scripts\spyder" "%%1"' % (pythonw , target ))
87+ winreg .SetValueEx (winreg .CreateKey (root , KEY_C1 % ("NoCon" , EWS )),
88+ "" , 0 , winreg .REG_SZ ,
89+ '"%s" "%s\Scripts\spyder" "%%1"' % (pythonw , target ))
6590
6691 # Icons
6792 dlls = osp .join (target , 'DLLs' )
68- pat2 = r"Software\Classes\Python.%sFile\DefaultIcon"
69- winreg .SetValueEx (winreg .CreateKey (root , pat2 % "" ),
93+ winreg .SetValueEx (winreg .CreateKey (root , KEY_I % "" ),
7094 "" , 0 , winreg .REG_SZ , r'%s\py.ico' % dlls )
71- winreg .SetValueEx (winreg .CreateKey (root , pat2 % "NoCon" ),
95+ winreg .SetValueEx (winreg .CreateKey (root , KEY_I % "NoCon" ),
7296 "" , 0 , winreg .REG_SZ , r'%s\py.ico' % dlls )
73- winreg .SetValueEx (winreg .CreateKey (root , pat2 % "Compiled" ),
97+ winreg .SetValueEx (winreg .CreateKey (root , KEY_I % "Compiled" ),
7498 "" , 0 , winreg .REG_SZ , r'%s\pyc.ico' % dlls )
7599
76100 # Descriptions
77- pat3 = r"Software\Classes\Python.%sFile"
78- winreg .SetValueEx (winreg .CreateKey (root , pat3 % "" ),
101+ winreg .SetValueEx (winreg .CreateKey (root , KEY_D % "" ),
79102 "" , 0 , winreg .REG_SZ , "Python File" )
80- winreg .SetValueEx (winreg .CreateKey (root , pat3 % "NoCon" ),
103+ winreg .SetValueEx (winreg .CreateKey (root , KEY_D % "NoCon" ),
81104 "" , 0 , winreg .REG_SZ , "Python File (no console)" )
82- winreg .SetValueEx (winreg .CreateKey (root , pat3 % "Compiled" ),
105+ winreg .SetValueEx (winreg .CreateKey (root , KEY_D % "Compiled" ),
83106 "" , 0 , winreg .REG_SZ , "Compiled Python File" )
84107
85108 # Create start menu entries for all WinPython launchers
86- wpgroup = utils .create_winpython_start_menu_folder (current = current )
87- wpdir = osp .join (target , os .pardir )
88- for name in os .listdir (wpdir ):
89- bname , ext = osp .splitext (name )
90- if ext == '.exe' :
91- utils .create_shortcut (osp .join (wpdir , name ), bname ,
92- osp .join (wpgroup , bname ))
109+ for path , desc , fname in _get_shortcut_data (target , current = current ):
110+ utils .create_shortcut (path , desc , fname )
93111
94112 # Register the Python ActiveX Scripting client (requires pywin32)
95113 axscript = osp .join (target , 'Lib' , 'site-packages' , 'win32comext' ,
@@ -101,5 +119,38 @@ def register(target, current=True):
101119 file = sys .stderr )
102120
103121
122+ def unregister (target , current = True ):
123+ """Unregister a Python distribution in Windows registry"""
124+ # Registry entries
125+ root = winreg .HKEY_CURRENT_USER if current else winreg .HKEY_LOCAL_MACHINE
126+ for key in (
127+ # Icons
128+ KEY_I % "NoCon" , KEY_I % "Compiled" , KEY_I % "" ,
129+ # Edit with IDLE
130+ KEY_C1 % ("" , EWI ), KEY_C1 % ("NoCon" , EWI ),
131+ KEY_C0 % ("" , EWI ), KEY_C0 % ("NoCon" , EWI ),
132+ # Edit with Spyder
133+ KEY_C1 % ("" , EWS ), KEY_C1 % ("NoCon" , EWS ),
134+ KEY_C0 % ("" , EWS ), KEY_C0 % ("NoCon" , EWS ),
135+ # Verbs
136+ KEY_C1 % ("" , "open" ), KEY_C1 % ("NoCon" , "open" ),
137+ KEY_C1 % ("Compiled" , "open" ),
138+ # Descriptions
139+ KEY_D % "NoCon" , KEY_D % "Compiled" , KEY_D % "" ,
140+ # Parent key
141+ KEY_C ,
142+ ):
143+ try :
144+ winreg .DeleteKey (root , key )
145+ except WindowsError :
146+ rootkey = 'HKEY_CURRENT_USER' if current else 'HKEY_LOCAL_MACHINE'
147+ raise WindowsError (r'Unable to remove %s\%s' % (rootkey , key ))
148+
149+ # Start menu shortcuts
150+ for path , desc , fname in _get_shortcut_data (target , current = current ):
151+ os .remove (fname )
152+
153+
104154if __name__ == '__main__' :
105155 register (sys .prefix )
156+ unregister (sys .prefix )
0 commit comments