14
16
# along with this program; if not, write to the Free Software
15
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
Set of functions to work with console on Windows.
20
Author: Alexander Belchenko (e-mail: bialix AT ukr.net)
21
License: Public domain
19
"""Win32-specific helper functions
21
Only one dependency: ctypes should be installed.
30
if sys.platform == 'win32':
31
_major,_minor,_build,_platform,_text = sys.getwindowsversion()
33
raise Exception('This platform does not supported!')
26
42
# We can cope without it; use a separate variable to help pyflakes
30
46
except ImportError:
49
if winver == 'Windows 98':
50
create_buffer = ctypes.create_string_buffer
53
create_buffer = ctypes.create_unicode_buffer
57
# Special Win32 API constants
58
# Handles of std streams
34
59
WIN32_STDIN_HANDLE = -10
35
60
WIN32_STDOUT_HANDLE = -11
36
61
WIN32_STDERR_HANDLE = -12
63
# CSIDL constants (from MSDN 2003)
64
CSIDL_APPDATA = 0x001A # Application Data folder
65
CSIDL_PERSONAL = 0x0005 # My Documents folder
67
# from winapi C headers
70
MAX_COMPUTERNAME_LENGTH = 31
39
73
def get_console_size(defaultx=80, defaulty=25):
40
""" Return size of current console.
42
This function try to determine actual size of current working
43
console window and return tuple (sizex, sizey) if success,
44
or default size (defaultx, defaulty) otherwise.
46
Dependencies: ctypes should be installed.
50
return (defaultx, defaulty)
52
# To avoid problem with redirecting output via pipe
53
# need to use stderr instead of stdout
54
h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE)
55
csbi = ctypes.create_string_buffer(22)
56
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
59
(bufx, bufy, curx, cury, wattr,
74
"""Return size of current console.
76
This function try to determine actual size of current working
77
console window and return tuple (sizex, sizey) if success,
78
or default size (defaultx, defaulty) otherwise.
82
return (defaultx, defaulty)
84
# To avoid problem with redirecting output via pipe
85
# need to use stderr instead of stdout
86
h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE)
87
csbi = ctypes.create_string_buffer(22)
88
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
91
(bufx, bufy, curx, cury, wattr,
60
92
left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
61
sizex = right - left + 1
62
sizey = bottom - top + 1
65
return (defaultx, defaulty)
93
sizex = right - left + 1
94
sizey = bottom - top + 1
97
return (defaultx, defaulty)
100
def get_appdata_location():
101
"""Return Application Data location.
102
Return None if we cannot obtain location.
104
Returned value can be unicode or plain sring.
105
To convert plain string to unicode use
106
s.decode(bzrlib.user_encoding)
110
SHGetSpecialFolderPath = \
111
ctypes.windll.shell32.SHGetSpecialFolderPathW
112
except AttributeError:
115
buf = ctypes.create_unicode_buffer(MAX_PATH)
116
if SHGetSpecialFolderPath(None,buf,CSIDL_APPDATA,0):
119
appdata = os.environ.get('APPDATA')
122
# if we fall to this point we on win98
123
# at least try C:/WINDOWS/Application Data
124
windir = os.environ.get('windir')
126
appdata = os.path.join(windir, 'Application Data')
127
if os.path.isdir(appdata):
129
# did not find anything
133
def get_home_location():
134
"""Return user's home location.
135
Assume on win32 it's the <My Documents> folder.
136
If location cannot be obtained return system drive root,
139
Returned value can be unicode or plain sring.
140
To convert plain string to unicode use
141
s.decode(bzrlib.user_encoding)
145
SHGetSpecialFolderPath = \
146
ctypes.windll.shell32.SHGetSpecialFolderPathW
147
except AttributeError:
150
buf = ctypes.create_unicode_buffer(MAX_PATH)
151
if SHGetSpecialFolderPath(None,buf,CSIDL_PERSONAL,0):
153
# try for HOME env variable
154
home = os.path.expanduser('~')
157
# at least return windows root directory
158
windir = os.environ.get('windir')
160
return os.path.splitdrive(windir) + '/'
161
# otherwise C:\ is good enough for 98% users
166
"""Return user name as login name.
167
If name cannot be obtained return None.
169
Returned value can be unicode or plain sring.
170
To convert plain string to unicode use
171
s.decode(bzrlib.user_encoding)
175
advapi32 = ctypes.windll.advapi32
176
GetUserName = getattr(advapi32, 'GetUserName'+suffix)
177
except AttributeError:
180
buf = create_buffer(UNLEN+1)
181
n = ctypes.c_int(UNLEN+1)
182
if GetUserName(buf, ctypes.byref(n)):
184
# otherwise try env variables
185
return os.environ.get('USERNAME', None)
189
"""Return host machine name.
190
If name cannot be obtained return None.
192
Returned value can be unicode or plain sring.
193
To convert plain string to unicode use
194
s.decode(bzrlib.user_encoding)
198
kernel32 = ctypes.windll.kernel32
199
GetComputerName = getattr(kernel32, 'GetComputerName'+suffix)
200
except AttributeError:
203
buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
204
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
205
if GetComputerName(buf, ctypes.byref(n)):
207
# otherwise try env variables
208
return os.environ.get('COMPUTERNAME', None)
211
def _ensure_unicode(s):
212
if s and type(s) != unicode:
214
s = s.decode(bzrlib.user_encoding)
218
def get_appdata_location_unicode():
219
return _ensure_unicode(get_appdata_location())
221
def get_home_location_unicode():
222
return _ensure_unicode(get_home_location())
224
def get_user_name_unicode():
225
return _ensure_unicode(get_user_name())
227
def get_host_name_unicode():
228
return _ensure_unicode(get_host_name())