/
register-leo.leox
157 lines (136 loc) · 5.8 KB
/
register-leo.leox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# -*- coding: utf-8 -*-
#@+leo-ver=5-thin
#@+node:maphew.20130611235500.2658: * @file register-leo.leox
#@@first
#@@language python
#@@tabwidth -4
"""Add registry keys for Leo file type and .leo file association"""
#@+others
#@+node:mhw-debug-1081.20190216130451.1: ** imports
import leo
import leo.core.leoGlobals as g
import os
import sys
import shutil
import subprocess
from winreg import *
#@+node:maphew.20130510011223.1645: ** docstring
"""Tell Windows how to handle .leo files, enables double clicking on them to open.
To run: in Leo make this the active node and press [Ctrl-B] (execute-script)
Requires elevated User Account Control (UAC) privileges.
See http://superuser.com/questions/88491/force-cmd-exe-to-run-as-admin/
Resources used:
@url http://stackoverflow.com/questions/2331690/how-to-set-a-icon-file-while-creating-file
@url http://stackoverflow.com/questions/771689/how-can-i-set-an-icon-for-my-own-file-extension
@url https://stackoverflow.com/questions/130763/request-uac-elevation-from-within-a-python-script
"""
#@+node:mhw-debug-1081.20190227224730.1: ** get_leo_libpath
def get_leo_libpath():
"""Return Leo's library path (ie: ./leo-editor/leo or PYTHONHOME/Lib/site-packages/leo)"""
import leo
return leo.__path__[0]
#@+node:mhw-debug-1081.20190221070850.1: ** get_launch_leo
def get_launch_leo():
"""Prefer leo exe script in PATH over launchLeo.py relative to Leo library"""
leo_script = os.path.join(sys.exec_prefix, "Scripts", "leo.exe")
if os.path.isfile(leo_script):
return leo_script
else:
leo_script = os.path.join(get_leo_libpath(), "../launchLeo.py")
if os.path.isfile(leo_script):
return leo_script
return None
#@+node:maphew.20130509185752.1607: ** register_leo
def register_leo(pyexe, launchLeo, icon):
"""Create registry key for Leo file type, set default icon and launch command
"""
g.es_print("Attempting to register leo filetype with Windows...")
g.es_print(" Python:", pyexe)
g.es_print(" Leo:", launchLeo)
if g.os_path_exists(icon):
g.es_print(" Found:", icon)
#@+<<filetype>>
#@+node:maphew.20130515233516.1659: *3* <<filetype>>
try:
leoKey = CreateKey(HKEY_CLASSES_ROOT, "Leo.File")
iconKey = CreateKey(leoKey, "DefaultIcon")
shellKey = CreateKey(leoKey, "Shell")
openKey = CreateKey(shellKey, "Open")
cmdKey = CreateKey(openKey, "Command")
SetValue(leoKey, None, REG_SZ, "Leo Editor File")
SetValue(iconKey, None, REG_SZ, icon)
if "launchLeo.py" in launchLeo:
SetValueEx(
cmdKey,
None,
None,
REG_EXPAND_SZ,
'"{0}" "{1}" "%1" %*'.format(pyexe, launchLeo),
)
else:
SetValueEx(cmdKey, None, None, REG_EXPAND_SZ, '"{0}" "%1" %*'.format(launchLeo))
for k in (leoKey, iconKey, shellKey, openKey, cmdKey):
CloseKey(k)
g.es_print(" Registered!")
except WindowsError as e:
g.es_print(" Failed:", e)
#@-<<filetype>>
#@+<<association>>
#@+node:maphew.20130515233516.1660: *3* <<association>>
try:
leoKey = CreateKey(HKEY_CLASSES_ROOT, ".leo")
SetValue(leoKey, None, REG_SZ, "Leo.File")
# SetValue(leoKey, "Content Type", REG_SZ, "text/xml") #creates a sub_key instead of a value :(
CloseKey(leoKey)
leoKey = CreateKey(HKEY_CLASSES_ROOT, ".leox")
SetValue(leoKey, None, REG_SZ, "Leo.File")
CloseKey(leoKey)
leoKey = CreateKey(HKEY_CLASSES_ROOT, ".leojs")
SetValue(leoKey, None, REG_SZ, "Leo.File")
CloseKey(leoKey)
g.es_print(" .leo, .leojs and .leox files associated as 'Leo.File'")
except WindowsError as e:
g.es_print(" Failed:", e)
#@-<<association>>
else:
g.es_print(" LeoDoc.ico not in expected location, can't continue.")
#@+node:mhw-debug-1081.20190314005003.1: ** relaunch_elevated
def relaunch_elevated(script):
g.es_print("--- Relaunching and asking for elevated permissions")
g.execute_shell_commands(["&{} {} {}".format(sys.executable, elevate, script)])
g.es_print("---")
#@+node:mhw-debug-1081.20190314004045.1: ** get_my_path
def get_my_path():
"""Return full path of currently running script or executable
Thanks to
https://stackoverflow.com/questions/2632199/
how-do-i-get-the-path-of-the-current-executed-file-in-python
@jose-crespo-barrios, https://stackoverflow.com/a/44592299/14420
"""
import inspect
filename = inspect.getframeinfo(inspect.currentframe()).filename
return filename
#@-others
# define script names and paths
scripts_path = os.path.realpath(os.path.join(leo.__path__[0], "scripts/win"))
elevate = os.path.join(scripts_path, "elevate.py")
#this_script = get_my_path() # #1376, works for python and ctrl-b but not --script=xx
this_script = os.path.join(scripts_path, "register-leo.leox")
g.es_print("--- Running register-leo Leo script")
g.es_print(scripts_path)
g.es_print(elevate, this_script)
import ctypes, sys
if not ctypes.windll.shell32.IsUserAnAdmin():
g.es_print("No admin privileges")
relaunch_elevated(this_script)
else:
pyexe = g.sys.executable
pywexe = pyexe.replace("python.exe", "pythonw.exe")
# launchLeo = g.os_path_finalize_join(g.computeLeoDir(), '../launchLeo.py')
launchLeo = get_launch_leo()
icon = "%s\Icons\LeoDoc.ico" % get_leo_libpath()
# # 'pyexe' to launch GUI with a console window for messages
# # 'pywexe' to launch GUI only (will lose messages that bypass log)
register_leo(pywexe, launchLeo, icon)
g.es_print("--- end of script")
#@-leo