Jean-Paul Calderone Jean-Paul Calderone - 1 month ago 19
Python Question

What is the Windows equivalent of pwd.getpwnam(username).pw_dir?

The Python pwd module provides access to

getpwnam(3)
POSIX API, which can be used to get the home directory for a particular user by username, as well determining if the username is valid at all.
pwd.getpwnam
will raise an exception if called with a non-existent username.

At first it seems like the same result can be achieved in a cross-platform manner via
os.path.expanduser('~username')
. However, it appears that with Python 2.6 on Windows XP this won't actually produce a failure for a non-existent username. Furthermore, on Python 2.5 on Windows XP, it seems to fail even for valid users.

Can this information be obtained reliably on Windows? How?

Answer

Reading the 2.6 documentation shows that os.path.expanduser() is broken on Windows:

On Windows, HOME and USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used. An initial ~user is handled by stripping the last directory component from the created user path derived above.

Say whaat? This assumes all user homes have to be under the same parent directory. Nuh-ugh!

It was a bit hard to dig but here is a solution that will look up a local user by given name:

from win32security import LookupAccountName, ConvertSidToStringSid
from _winreg import OpenKey, QueryValueEx, HKEY_LOCAL_MACHINE

def getUserDir(userName):
    ssid = ConvertSidToStringSid(LookupAccountName(None, userName)[0])
    key = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\\' + ssid)
    return QueryValueEx(key, 'ProfileImagePath')[0]