64
70
if winver == 'Windows 98':
65
71
create_buffer = ctypes.create_string_buffer
72
def extract_buffer(buf):
73
return buf.value.decode("mbcs")
68
76
create_buffer = ctypes.create_unicode_buffer
77
extract_buffer = operator.attrgetter("value")
248
257
one that moves with the user as they logon to different machines, and
249
258
a 'local' one that stays local to the machine. This returns the 'roaming'
250
259
directory, and thus is suitable for storing user-preferences, etc.
252
Returned value can be unicode or plain string.
253
To convert plain string to unicode use
254
s.decode(osutils.get_user_encoding())
255
(XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
257
261
appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
261
appdata = os.environ.get('APPDATA')
264
# if we fall to this point we on win98
265
# at least try C:/WINDOWS/Application Data
266
windir = os.environ.get('windir')
268
appdata = os.path.join(windir, 'Application Data')
269
if os.path.isdir(appdata):
271
# did not find anything
264
# Use APPDATA if defined, will return None if not
265
return get_environ_unicode('APPDATA')
275
268
def get_local_appdata_location():
281
274
a 'local' one that stays local to the machine. This returns the 'local'
282
275
directory, and thus is suitable for caches, temp files and other things
283
276
which don't need to move with the user.
285
Returned value can be unicode or plain string.
286
To convert plain string to unicode use
287
s.decode(osutils.get_user_encoding())
288
(XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
290
278
local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
293
281
# Vista supplies LOCALAPPDATA, but XP and earlier do not.
294
local = os.environ.get('LOCALAPPDATA')
282
local = get_environ_unicode('LOCALAPPDATA')
297
285
return get_appdata_location()
302
290
Assume on win32 it's the <My Documents> folder.
303
291
If location cannot be obtained return system drive root,
306
Returned value can be unicode or plain string.
307
To convert plain string to unicode use
308
s.decode(osutils.get_user_encoding())
310
294
home = _get_sh_special_folder_path(CSIDL_PERSONAL)
313
# try for HOME env variable
314
home = os.path.expanduser('~')
297
home = get_environ_unicode('HOME')
300
homepath = get_environ_unicode('HOMEPATH')
301
if homepath is not None:
302
return os.path.join(get_environ_unicode('HOMEDIR', ''), home)
317
303
# at least return windows root directory
318
windir = os.environ.get('windir')
304
windir = get_environ_unicode('WINDIR')
320
306
return os.path.splitdrive(windir)[0] + '/'
321
307
# otherwise C:\ is good enough for 98% users
308
return unicode('C:/')
325
311
def get_user_name():
326
312
"""Return user name as login name.
327
313
If name cannot be obtained return None.
329
Returned value can be unicode or plain string.
330
To convert plain string to unicode use
331
s.decode(osutils.get_user_encoding())
340
322
buf = create_buffer(UNLEN+1)
341
323
n = ctypes.c_int(UNLEN+1)
342
324
if GetUserName(buf, ctypes.byref(n)):
325
return extract_buffer(buf)
344
326
# otherwise try env variables
345
return os.environ.get('USERNAME', None)
327
return get_environ_unicode('USERNAME')
348
330
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
353
335
"""Return host machine name.
354
336
If name cannot be obtained return None.
356
:return: A unicode string representing the host name. On win98, this may be
357
a plain string as win32 api doesn't support unicode.
338
:return: A unicode string representing the host name.
377
358
if (GetComputerNameEx is not None
378
359
and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
379
360
buf, ctypes.byref(n))):
361
return extract_buffer(buf)
382
363
# Try GetComputerName in case GetComputerNameEx wasn't found
383
364
# It returns the NETBIOS name, which isn't as good, but still ok.
388
369
if (GetComputerName is not None
389
370
and GetComputerName(buf, ctypes.byref(n))):
391
# otherwise try env variables, which will be 'mbcs' encoded
392
# on Windows (Python doesn't expose the native win32 unicode environment)
394
# http://msdn.microsoft.com/en-us/library/aa246807.aspx
395
# environment variables should always be encoded in 'mbcs'.
397
return os.environ['COMPUTERNAME'].decode("mbcs")
371
return extract_buffer(buf)
372
return get_environ_unicode('COMPUTERNAME')
375
@symbol_versioning.deprecated_method(
376
symbol_versioning.deprecated_in((2, 5, 0)))
402
377
def _ensure_unicode(s):
403
378
if s and type(s) != unicode:
404
379
from bzrlib import osutils
409
def get_appdata_location_unicode():
410
return _ensure_unicode(get_appdata_location())
412
def get_home_location_unicode():
413
return _ensure_unicode(get_home_location())
415
def get_user_name_unicode():
416
return _ensure_unicode(get_user_name())
418
def get_host_name_unicode():
419
return _ensure_unicode(get_host_name())
384
get_appdata_location_unicode = symbol_versioning.deprecated_method(
385
symbol_versioning.deprecated_in((2, 5, 0)))(get_appdata_location)
387
get_home_location_unicode = symbol_versioning.deprecated_method(
388
symbol_versioning.deprecated_in((2, 5, 0)))(get_home_location)
390
get_user_name_unicode = symbol_versioning.deprecated_method(
391
symbol_versioning.deprecated_in((2, 5, 0)))(get_user_name)
393
get_host_name_unicode = symbol_versioning.deprecated_method(
394
symbol_versioning.deprecated_in((2, 5, 0)))(get_host_name)
422
397
def _ensure_with_dir(path):
572
if has_ctypes and winver != 'Windows 98':
546
if has_ctypes and winver == 'Windows NT':
573
547
def get_unicode_argv():
574
548
prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
575
549
GetCommandLineW = prototype(("GetCommandLineW",
580
554
# Skip the first argument, since we only care about parameters
581
555
argv = _command_line_to_argv(command_line, sys.argv)[1:]
559
def get_environ_unicode(key, default=None):
560
"""Get `key` from environment as unicode or `default` if unset
562
The environment is natively unicode on modern windows versions but
563
Python 2 only accesses it through the legacy bytestring api.
565
Environmental variable names are case insenstive on Windows.
567
A large enough buffer will be allocated to retrieve the value, though
568
it may take two calls to the underlying library function.
570
This needs ctypes because pywin32 does not expose the wide version.
572
cfunc = getattr(get_environ_unicode, "_c_function", None)
574
from ctypes.wintypes import DWORD, LPCWSTR, LPWSTR
575
cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
576
("GetEnvironmentVariableW", ctypes.windll.kernel32))
577
get_environ_unicode._c_function = cfunc
578
buffer_size = 256 # heuristic, 256 characters often enough
580
buffer = ctypes.create_unicode_buffer(buffer_size)
581
length = cfunc(key, buffer, buffer_size)
583
code = ctypes.GetLastError()
584
if code == 203: # ERROR_ENVVAR_NOT_FOUND
586
raise ctypes.WinError(code)
587
if buffer_size > length:
588
return buffer[:length]
584
591
get_unicode_argv = None
592
def get_environ_unicode(key, default=None):
593
"""Get `key` from environment as unicode or `default` if unset
595
Fallback version that should basically never be needed.
598
return os.environ[key].decode("mbcs")