-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
208 lines (177 loc) · 6.54 KB
/
__init__.py
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import argparse
import ast
import sys
import tempfile
import os
import pathlib
import subprocess
from typing import Union
from subprocesshidden import Popen
def escapepa(p):
return os.path.normpath(p).replace("\\", "\\\\")
def escapeargu(p):
if not p:
return []
if not isinstance(p, list):
p = [p]
allali = []
for pp in p:
allali.append(pp.replace("\\", "\\\\").replace('"', '\\"'))
return allali
def create_shortcut(
shortcut_path: str,
target: str,
arguments: list,
hotkey="",
working_dir: Union[str, None] = None,
minimized_maximized_normal: str = "minimized",
asadmin: bool = False,
) -> str:
"""
Creates a Windows shortcut (.lnk) file at the specified path with the specified properties.
Args:
shortcut_path (str): The path where the shortcut file will be created.
target (str): The path of the target file or application that the shortcut will point to.
arguments (list): A list of arguments to be passed to the target file or application.
hotkey (str, optional): The hotkey combination to activate the shortcut. Defaults to "".
working_dir (Union[str, None], optional): The working directory for the target file or application. Defaults to None.
minimized_maximized_normal (str, optional): The window state of the target application when the shortcut is activated.
Possible values are "minimized", "maximized", or "normal". Defaults to "minimized".
asadmin (bool, optional): If True, the shortcut will be created with administrative privileges. Defaults to False.
Returns:
str: The JavaScript content used to create the shortcut.
Raises:
OSError: If the shortcut file cannot be created.
"""
wco = 4
if minimized_maximized_normal == "minimized":
wco = 7
elif minimized_maximized_normal == "maximized":
wco = 0
shortcut_path2 = pathlib.Path(shortcut_path)
shortcut_path2.parent.mkdir(parents=True, exist_ok=True)
if str(working_dir) == "None":
working_dir = None
if not working_dir:
working_dir = os.path.normpath(os.path.dirname(target))
working_dir = escapepa(working_dir)
shortcut_path = escapepa(shortcut_path)
target = escapepa(target)
if not arguments:
arguments = ""
if isinstance(arguments, list):
arguments = " ".join(arguments)
if isinstance(arguments, list):
arguments = " ".join(arguments)
arguments = " ".join(escapeargu(arguments))
js_content = f"""
var sh = WScript.CreateObject("WScript.Shell");
var shortcut = sh.CreateShortcut("{shortcut_path}");
shortcut.WindowStyle = {wco};
shortcut.TargetPath = "{target}";
shortcut.Hotkey = "{hotkey}";
shortcut.Arguments = "{arguments}";
shortcut.WorkingDirectory = "{working_dir}";
shortcut.IconLocation = "{target}";
shortcut.Save();"""
fd, path = tempfile.mkstemp(".js")
try:
with os.fdopen(fd, "w") as f:
f.write(js_content)
p = Popen(
[r"wscript.exe", path],
shell=False,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
p.wait(5)
finally:
try:
os.unlink(path)
except Exception as fe:
pass
if asadmin:
with open(shortcut_path, "rb") as f:
ba = bytearray(f.read())
ba[0x15] = ba[0x15] | 0x20
with open(shortcut_path, "wb") as f:
f.write(ba)
return js_content
def asteval(x):
try:
return ast.literal_eval(str(x))
except Exception:
return x
def npath(x):
try:
return os.path.normpath(str(x))
except Exception:
return x
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=65)
)
parser.add_argument(
"--shortcut_path",
help=r"""The path where the shortcut file will be created.""",
)
parser.add_argument(
"--target",
default="",
help=r"""The path to the target file or application that the shortcut will launch.""",
)
parser.add_argument(
"--hotkey",
default="",
help=r"""Hotkey for opening the lnk file. Defaults to ''.""",
)
parser.add_argument(
"--working_dir",
default="None",
help=r"""The working directory for the target file or application. (Working dict of shortcut_path).""",
)
parser.add_argument(
"--mode",
default="minimized",
help=r"""The window state of the target application when launched. Can be "normal", "minimized" or "maximized" """,
)
parser.add_argument(
"--asadmin",
default="False",
help=r"""Whether to run the shortcut as an administrator. Defaults to False.""",
)
parser.add_argument(
r"--args",
default="",
help=r"""Arguments to be passed to the target file or application as they would receive them. Example:
lnkgonewild.exe --shortcut_path C:\Users\hansc\Desktop\testlink.lnk --target C:\cygwin\bin\lsattr.exe --hotkey Ctrl+Alt+q --working_dir None --mode minimized --silentlog None --asadmin False --arguments -a -d""",
)
if len(sys.argv) < 3:
parser.print_help()
else:
try:
argsindex = sys.argv.index("--args")
args_ = sys.argv[argsindex + 1 :].copy()
sys.argv = sys.argv[:argsindex]
args_ = " ".join(args_).strip()
print(args_)
except Exception:
args_ = "[]"
args = parser.parse_args()
shortcut_path = npath(asteval(args.shortcut_path))
target = npath(asteval(args.target))
arguments = asteval(args_)
hotkey = asteval(args.hotkey)
working_dir = npath(asteval(args.working_dir))
minimized_maximized_normal_invisible = asteval(args.mode)
asadmin = asteval(args.asadmin)
create_shortcut(
shortcut_path=shortcut_path,
target=target,
arguments=arguments,
minimized_maximized_normal=minimized_maximized_normal_invisible, #
asadmin=asadmin, # enables the admin check box
hotkey=hotkey,
working_dir=working_dir,
)