associate.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright © 2012 Pierre Raybaut
  4. # Licensed under the terms of the MIT License
  5. # (see winpython/__init__.py for details)
  6. """
  7. Register a Python distribution
  8. Created on Tue Aug 21 21:46:30 2012
  9. """
  10. from __future__ import print_function
  11. import sys
  12. import os
  13. import os.path as osp
  14. import subprocess
  15. # Local imports
  16. from winpython.py3compat import winreg
  17. from winpython import utils
  18. KEY_C = r"Software\Classes\%s"
  19. KEY_C0 = KEY_C % r"Python.%sFile\shell"
  20. KEY_C1 = KEY_C % r"Python.%sFile\shell\%s"
  21. KEY_C2 = KEY_C1 + r"\command"
  22. KEY_DROP0 = KEY_C % r"Python.%sFile\shellex"
  23. KEY_DROP1 = KEY_C % r"Python.%sFile\shellex\DropHandler"
  24. KEY_I = KEY_C % r"Python.%sFile\DefaultIcon"
  25. KEY_D = KEY_C % r"Python.%sFile"
  26. EWI = "Edit with IDLE"
  27. EWS = "Edit with Spyder"
  28. KEY_S = r"Software\Python"
  29. KEY_S0 = KEY_S + r"\PythonCore"
  30. KEY_S1 = KEY_S0 + r"\%s"
  31. def _get_shortcut_data(target, current=True):
  32. wpgroup = utils.create_winpython_start_menu_folder(
  33. current=current
  34. )
  35. wpdir = osp.join(target, os.pardir)
  36. data = []
  37. for name in os.listdir(wpdir):
  38. bname, ext = osp.splitext(name)
  39. if ext == '.exe':
  40. data.append(
  41. (
  42. osp.join(wpdir, name),
  43. bname,
  44. osp.join(wpgroup, bname),
  45. )
  46. )
  47. return data
  48. def register(target, current=True):
  49. """Register a Python distribution in Windows registry"""
  50. root = (
  51. winreg.HKEY_CURRENT_USER
  52. if current
  53. else winreg.HKEY_LOCAL_MACHINE
  54. )
  55. # Extensions
  56. winreg.SetValueEx(
  57. winreg.CreateKey(root, KEY_C % ".py"),
  58. "",
  59. 0,
  60. winreg.REG_SZ,
  61. "Python.File",
  62. )
  63. winreg.SetValueEx(
  64. winreg.CreateKey(root, KEY_C % ".pyw"),
  65. "",
  66. 0,
  67. winreg.REG_SZ,
  68. "Python.NoConFile",
  69. )
  70. winreg.SetValueEx(
  71. winreg.CreateKey(root, KEY_C % ".pyc"),
  72. "",
  73. 0,
  74. winreg.REG_SZ,
  75. "Python.CompiledFile",
  76. )
  77. winreg.SetValueEx(
  78. winreg.CreateKey(root, KEY_C % ".pyo"),
  79. "",
  80. 0,
  81. winreg.REG_SZ,
  82. "Python.CompiledFile",
  83. )
  84. # MIME types
  85. winreg.SetValueEx(
  86. winreg.CreateKey(root, KEY_C % ".py"),
  87. "Content Type",
  88. 0,
  89. winreg.REG_SZ,
  90. "text/plain",
  91. )
  92. winreg.SetValueEx(
  93. winreg.CreateKey(root, KEY_C % ".pyw"),
  94. "Content Type",
  95. 0,
  96. winreg.REG_SZ,
  97. "text/plain",
  98. )
  99. # Verbs
  100. python = osp.abspath(osp.join(target, 'python.exe'))
  101. pythonw = osp.abspath(osp.join(target, 'pythonw.exe'))
  102. spyder = osp.abspath(
  103. osp.join(target, os.pardir, 'Spyder.exe')
  104. )
  105. if not osp.isfile(spyder):
  106. spyder = '%s" "%s\Scripts\spyder' % (
  107. pythonw,
  108. target,
  109. )
  110. winreg.SetValueEx(
  111. winreg.CreateKey(root, KEY_C2 % ("", "open")),
  112. "",
  113. 0,
  114. winreg.REG_SZ,
  115. '"%s" "%%1" %%*' % python,
  116. )
  117. winreg.SetValueEx(
  118. winreg.CreateKey(root, KEY_C2 % ("NoCon", "open")),
  119. "",
  120. 0,
  121. winreg.REG_SZ,
  122. '"%s" "%%1" %%*' % pythonw,
  123. )
  124. winreg.SetValueEx(
  125. winreg.CreateKey(
  126. root, KEY_C2 % ("Compiled", "open")
  127. ),
  128. "",
  129. 0,
  130. winreg.REG_SZ,
  131. '"%s" "%%1" %%*' % python,
  132. )
  133. winreg.SetValueEx(
  134. winreg.CreateKey(root, KEY_C2 % ("", EWI)),
  135. "",
  136. 0,
  137. winreg.REG_SZ,
  138. '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
  139. % (pythonw, target),
  140. )
  141. winreg.SetValueEx(
  142. winreg.CreateKey(root, KEY_C2 % ("NoCon", EWI)),
  143. "",
  144. 0,
  145. winreg.REG_SZ,
  146. '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
  147. % (pythonw, target),
  148. )
  149. winreg.SetValueEx(
  150. winreg.CreateKey(root, KEY_C2 % ("", EWS)),
  151. "",
  152. 0,
  153. winreg.REG_SZ,
  154. '"%s" "%%1"' % spyder,
  155. )
  156. winreg.SetValueEx(
  157. winreg.CreateKey(root, KEY_C2 % ("NoCon", EWS)),
  158. "",
  159. 0,
  160. winreg.REG_SZ,
  161. '"%s" "%%1"' % spyder,
  162. )
  163. # Drop support
  164. handler = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
  165. for ftype in ("", "NoCon", "Compiled"):
  166. winreg.SetValueEx(
  167. winreg.CreateKey(root, KEY_DROP1 % ftype),
  168. "",
  169. 0,
  170. winreg.REG_SZ,
  171. handler,
  172. )
  173. # Icons
  174. dlls = osp.join(target, 'DLLs')
  175. winreg.SetValueEx(
  176. winreg.CreateKey(root, KEY_I % ""),
  177. "",
  178. 0,
  179. winreg.REG_SZ,
  180. r'%s\py.ico' % dlls,
  181. )
  182. winreg.SetValueEx(
  183. winreg.CreateKey(root, KEY_I % "NoCon"),
  184. "",
  185. 0,
  186. winreg.REG_SZ,
  187. r'%s\py.ico' % dlls,
  188. )
  189. winreg.SetValueEx(
  190. winreg.CreateKey(root, KEY_I % "Compiled"),
  191. "",
  192. 0,
  193. winreg.REG_SZ,
  194. r'%s\pyc.ico' % dlls,
  195. )
  196. # Descriptions
  197. winreg.SetValueEx(
  198. winreg.CreateKey(root, KEY_D % ""),
  199. "",
  200. 0,
  201. winreg.REG_SZ,
  202. "Python File",
  203. )
  204. winreg.SetValueEx(
  205. winreg.CreateKey(root, KEY_D % "NoCon"),
  206. "",
  207. 0,
  208. winreg.REG_SZ,
  209. "Python File (no console)",
  210. )
  211. winreg.SetValueEx(
  212. winreg.CreateKey(root, KEY_D % "Compiled"),
  213. "",
  214. 0,
  215. winreg.REG_SZ,
  216. "Compiled Python File",
  217. )
  218. # PythonCore entries
  219. short_version = utils.get_python_infos(target)[0]
  220. long_version = utils.get_python_long_version(target)
  221. key_core = (KEY_S1 % short_version) + r'\%s'
  222. winreg.SetValueEx(
  223. winreg.CreateKey(root, key_core % 'InstallPath'),
  224. "",
  225. 0,
  226. winreg.REG_SZ,
  227. target,
  228. )
  229. winreg.SetValueEx(
  230. winreg.CreateKey(
  231. root, key_core % r'InstallPath\InstallGroup'
  232. ),
  233. "",
  234. 0,
  235. winreg.REG_SZ,
  236. "Python %s" % short_version,
  237. )
  238. winreg.SetValueEx(
  239. winreg.CreateKey(root, key_core % 'Modules'),
  240. "",
  241. 0,
  242. winreg.REG_SZ,
  243. "",
  244. )
  245. winreg.SetValueEx(
  246. winreg.CreateKey(root, key_core % 'PythonPath'),
  247. "",
  248. 0,
  249. winreg.REG_SZ,
  250. r"%s\Lib;%s\DLLs" % (target, target),
  251. )
  252. winreg.SetValueEx(
  253. winreg.CreateKey(
  254. root,
  255. key_core % r'Help\Main Python Documentation',
  256. ),
  257. "",
  258. 0,
  259. winreg.REG_SZ,
  260. r"%s\Doc\python%s.chm" % (target, long_version),
  261. )
  262. # Create start menu entries for all WinPython launchers
  263. for path, desc, fname in _get_shortcut_data(
  264. target, current=current
  265. ):
  266. utils.create_shortcut(path, desc, fname)
  267. # Register the Python ActiveX Scripting client (requires pywin32)
  268. axscript = osp.join(
  269. target,
  270. 'Lib',
  271. 'site-packages',
  272. 'win32comext',
  273. 'axscript',
  274. 'client',
  275. 'pyscript.py',
  276. )
  277. if osp.isfile(axscript):
  278. subprocess.call(
  279. '"%s" "%s"' % (python, axscript), cwd=target
  280. )
  281. else:
  282. print(
  283. 'Unable to register ActiveX: please install pywin32',
  284. file=sys.stderr,
  285. )
  286. def unregister(target, current=True):
  287. """Unregister a Python distribution in Windows registry"""
  288. # Registry entries
  289. root = (
  290. winreg.HKEY_CURRENT_USER
  291. if current
  292. else winreg.HKEY_LOCAL_MACHINE
  293. )
  294. short_version = utils.get_python_infos(target)[0]
  295. key_core = (KEY_S1 % short_version) + r'\%s'
  296. for key in (
  297. # Drop support
  298. KEY_DROP1 % "",
  299. KEY_DROP1 % "NoCon",
  300. KEY_DROP1 % "Compiled",
  301. KEY_DROP0 % "",
  302. KEY_DROP0 % "NoCon",
  303. KEY_DROP0 % "Compiled",
  304. # Icons
  305. KEY_I % "NoCon",
  306. KEY_I % "Compiled",
  307. KEY_I % "",
  308. # Edit with IDLE
  309. KEY_C2 % ("", EWI),
  310. KEY_C2 % ("NoCon", EWI),
  311. KEY_C1 % ("", EWI),
  312. KEY_C1 % ("NoCon", EWI),
  313. # Edit with Spyder
  314. KEY_C2 % ("", EWS),
  315. KEY_C2 % ("NoCon", EWS),
  316. KEY_C1 % ("", EWS),
  317. KEY_C1 % ("NoCon", EWS),
  318. # Verbs
  319. KEY_C2 % ("", "open"),
  320. KEY_C2 % ("NoCon", "open"),
  321. KEY_C2 % ("Compiled", "open"),
  322. KEY_C1 % ("", "open"),
  323. KEY_C1 % ("NoCon", "open"),
  324. KEY_C1 % ("Compiled", "open"),
  325. KEY_C0 % "",
  326. KEY_C0 % "NoCon",
  327. KEY_C0 % "Compiled",
  328. # Descriptions
  329. KEY_D % "NoCon",
  330. KEY_D % "Compiled",
  331. KEY_D % "",
  332. # PythonCore
  333. key_core % r'InstallPath\InstallGroup',
  334. key_core % 'InstallPath',
  335. key_core % 'Modules',
  336. key_core % 'PythonPath',
  337. key_core % r'Help\Main Python Documentation',
  338. key_core % 'Help',
  339. KEY_S1 % short_version,
  340. KEY_S0,
  341. KEY_S,
  342. ):
  343. try:
  344. print(key)
  345. winreg.DeleteKey(root, key)
  346. except WindowsError:
  347. rootkey = (
  348. 'HKEY_CURRENT_USER'
  349. if current
  350. else 'HKEY_LOCAL_MACHINE'
  351. )
  352. print(
  353. r'Unable to remove %s\%s' % (rootkey, key),
  354. file=sys.stderr,
  355. )
  356. # Start menu shortcuts
  357. for path, desc, fname in _get_shortcut_data(
  358. target, current=current
  359. ):
  360. if osp.exists(fname):
  361. os.remove(fname)
  362. if __name__ == '__main__':
  363. register(sys.prefix)
  364. unregister(sys.prefix)