aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/deprecated/python/win-unicode-console/win_unicode_console/unicode_argv.py
blob: d23bc05f12177d999d8a0bc1f80d456c3dd8ed72 (plain) (blame)
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
"""Get Unicode argv strings in Python 2 on Windows

get_full_unicode_argv based on
http://code.activestate.com/recipes/572200/

argv_setter_hook based on
https://mail.python.org/pipermail/python-list/2016-June/710183.html
"""

import sys
from ctypes import WinDLL, c_int, POINTER, byref
from ctypes.wintypes import LPCWSTR, LPWSTR

kernel32 = WinDLL("kernel32", use_last_error=True)
shell32 = WinDLL("shell32", use_last_error=True)

GetCommandLineW = kernel32.GetCommandLineW
GetCommandLineW.argtypes = ()
GetCommandLineW.restype = LPCWSTR

CommandLineToArgvW = shell32.CommandLineToArgvW
CommandLineToArgvW.argtypes = (LPCWSTR, POINTER(c_int))
CommandLineToArgvW.restype = POINTER(LPWSTR)

LocalFree = kernel32.LocalFree


def get_full_unicode_argv():
	cmd = GetCommandLineW()
	argc = c_int(0)
	argv = CommandLineToArgvW(cmd, byref(argc))
	py_argv = [arg for i, arg in zip(range(argc.value), argv)]
	LocalFree(argv)
	return py_argv

def get_unicode_argv():
	if original_argv == [""]:
		return [u""]
	
	new_argv = get_full_unicode_argv()[-len(original_argv):]
	
	if original_argv[0] == "-c":
		new_argv[0] = u"-c"
	
	return new_argv


original_argv = None

def argv_setter_hook(path):
	global original_argv
	
	if original_argv is not None: # already got it
		raise ImportError
	
	try:
		original_argv = sys.argv
	except AttributeError:
		pass
	else:
		enable()
	finally:
		raise ImportError

def enable():
	global original_argv
	
	if original_argv is None:
		try:
			original_argv = sys.argv
		except AttributeError: # in sitecustomize in Python 2
			sys.path_hooks[:0] = [argv_setter_hook]
			return
	
	sys.argv = get_unicode_argv()

def disable():
	if original_argv is not None:
		sys.argv = original_argv