An Alternative To Os.path.expanduser("~")?
In python 2.7.x, os.path.expanduser('~') is broken for Unicode. This means that you get an exception if the expansion of '~' has non-ascii characters in it. http://bugs.python.org/
Solution 1:
The bug report you link to includes a workaround script, which retrieves the relevant home directory information directly from the Win32 API:
import ctypes
from ctypes import windll, wintypes
classGUID(ctypes.Structure):
_fields_ = [
('Data1', wintypes.DWORD),
('Data2', wintypes.WORD),
('Data3', wintypes.WORD),
('Data4', wintypes.BYTE * 8)
]
def__init__(self, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8):
"""Create a new GUID."""
self.Data1 = l
self.Data2 = w1
self.Data3 = w2
self.Data4[:] = (b1, b2, b3, b4, b5, b6, b7, b8)
def__repr__(self):
b1, b2, b3, b4, b5, b6, b7, b8 = self.Data4
return'GUID(%x-%x-%x-%x%x%x%x%x%x%x%x)' % (
self.Data1, self.Data2, self.Data3, b1, b2, b3, b4, b5, b6, b7, b8)
# constants to be used according to the version on shell32
CSIDL_PROFILE = 40
FOLDERID_Profile = GUID(0x5E6C858F, 0x0E22, 0x4760, 0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73)
defexpand_user():
# get the function that we can find from Vista up, not the one in XP
get_folder_path = getattr(windll.shell32, 'SHGetKnownFolderPath', None)
if get_folder_path isnotNone:
# ok, we can use the new function which is recomended by the msdn
ptr = ctypes.c_wchar_p()
get_folder_path(ctypes.byref(FOLDERID_Profile), 0, 0, ctypes.byref(ptr))
return ptr.value
else:
# use the deprecated one found in XP and on for compatibility reasons
get_folder_path = getattr(windll.shell32, 'SHGetSpecialFolderPathW', None)
buf = ctypes.create_unicode_buffer(300)
get_folder_path(None, buf, CSIDL_PROFILE, False)
return buf.value
This expand_user()
function returns the home directory for the current user only.
Solution 2:
As pointed out in the comments you actually need a WinAPI call to obtain the value of the USERPROFILE
environment variable:
import ctypes
buf = ctypes.create_unicode_buffer(1024)
ctypes.windll.kernel32.GetEnvironmentVariableW(u"USERPROFILE", buf, 1024)
home_dir = buf.value
or, if you prefer the dedicated shell function:
CSIDL_PROFILE = 40
buf = ctypes.create_unicode_buffer(1024)
ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PROFILE, None, 0, buf)
print buf.value
Note that both snippets return the profile path, this is not necessary the same as home path.
Post a Comment for "An Alternative To Os.path.expanduser("~")?"