64
68
if winver == 'Windows 98':
65
69
create_buffer = ctypes.create_string_buffer
70
def extract_buffer(buf):
71
return buf.value.decode("mbcs")
68
74
create_buffer = ctypes.create_unicode_buffer
75
extract_buffer = operator.attrgetter("value")
248
255
one that moves with the user as they logon to different machines, and
249
256
a 'local' one that stays local to the machine. This returns the 'roaming'
250
257
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
259
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
262
# Use APPDATA if defined, will return None if not
263
return get_environ_unicode('APPDATA')
275
266
def get_local_appdata_location():
281
272
a 'local' one that stays local to the machine. This returns the 'local'
282
273
directory, and thus is suitable for caches, temp files and other things
283
274
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
276
local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
293
279
# Vista supplies LOCALAPPDATA, but XP and earlier do not.
294
local = os.environ.get('LOCALAPPDATA')
280
local = get_environ_unicode('LOCALAPPDATA')
297
283
return get_appdata_location()
302
288
Assume on win32 it's the <My Documents> folder.
303
289
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
292
home = _get_sh_special_folder_path(CSIDL_PERSONAL)
313
# try for HOME env variable
314
home = os.path.expanduser('~')
295
home = get_environ_unicode('HOME')
298
homepath = get_environ_unicode('HOMEPATH')
299
if homepath is not None:
300
return os.path.join(get_environ_unicode('HOMEDIR', ''), home)
317
301
# at least return windows root directory
318
windir = os.environ.get('windir')
302
windir = get_environ_unicode('WINDIR')
320
304
return os.path.splitdrive(windir)[0] + '/'
321
305
# otherwise C:\ is good enough for 98% users
306
return unicode('C:/')
325
309
def get_user_name():
326
310
"""Return user name as login name.
327
311
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
320
buf = create_buffer(UNLEN+1)
341
321
n = ctypes.c_int(UNLEN+1)
342
322
if GetUserName(buf, ctypes.byref(n)):
323
return extract_buffer(buf)
344
324
# otherwise try env variables
345
return os.environ.get('USERNAME', None)
325
return get_environ_unicode('USERNAME')
348
328
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
353
333
"""Return host machine name.
354
334
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.
336
:return: A unicode string representing the host name.
377
356
if (GetComputerNameEx is not None
378
357
and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
379
358
buf, ctypes.byref(n))):
359
return extract_buffer(buf)
382
361
# Try GetComputerName in case GetComputerNameEx wasn't found
383
362
# It returns the NETBIOS name, which isn't as good, but still ok.
388
367
if (GetComputerName is not None
389
368
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")
369
return extract_buffer(buf)
370
return get_environ_unicode('COMPUTERNAME')
373
@symbol_versioning.deprecated_method(
374
symbol_versioning.deprecated_in((2, 5, 0)))
402
375
def _ensure_unicode(s):
403
376
if s and type(s) != unicode:
404
377
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())
382
get_appdata_location_unicode = symbol_versioning.deprecated_method(
383
symbol_versioning.deprecated_in((2, 5, 0)))(get_appdata_location)
385
get_home_location_unicode = symbol_versioning.deprecated_method(
386
symbol_versioning.deprecated_in((2, 5, 0)))(get_home_location)
388
get_user_name_unicode = symbol_versioning.deprecated_method(
389
symbol_versioning.deprecated_in((2, 5, 0)))(get_user_name)
391
get_host_name_unicode = symbol_versioning.deprecated_method(
392
symbol_versioning.deprecated_in((2, 5, 0)))(get_host_name)
422
395
def _ensure_with_dir(path):
572
if has_ctypes and winver != 'Windows 98':
544
if has_ctypes and winver == 'Windows NT':
573
545
def get_unicode_argv():
574
546
prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
575
547
GetCommandLineW = prototype(("GetCommandLineW",
580
552
# Skip the first argument, since we only care about parameters
581
553
argv = _command_line_to_argv(command_line, sys.argv)[1:]
557
def get_environ_unicode(key, default=None):
558
"""Get `key` from environment as unicode or `default` if unset
560
The environment is natively unicode on modern windows versions but
561
Python 2 only accesses it through the legacy bytestring api.
563
Environmental variable names are case insenstive on Windows.
565
A large enough buffer will be allocated to retrieve the value, though
566
it may take two calls to the underlying library function.
568
This needs ctypes because pywin32 does not expose the wide version.
570
cfunc = getattr(get_environ_unicode, "_c_function", None)
572
from ctypes.wintypes import DWORD, LPCWSTR, LPWSTR
573
cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
574
("GetEnvironmentVariableW", ctypes.windll.kernel32))
575
get_environ_unicode._c_function = cfunc
576
buffer_size = 256 # heuristic, 256 characters often enough
578
buffer = ctypes.create_unicode_buffer(buffer_size)
579
length = cfunc(key, buffer, buffer_size)
581
code = ctypes.GetLastError()
582
if code == 203: # ERROR_ENVVAR_NOT_FOUND
584
raise ctypes.WinError(code)
585
if buffer_size > length:
586
return buffer[:length]
584
589
get_unicode_argv = None
590
def get_environ_unicode(key, default=None):
591
"""Get `key` from environment as unicode or `default` if unset
593
Fallback version that should basically never be needed.
596
return os.environ[key].decode("mbcs")