pwd.getpwnam(username).pw_dir 的 Windows 等价物是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3305787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:53:03  来源:igfitidea点击:

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

pythonwindowshome-directory

提问by Jean-Paul Calderone

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.getpwnamwill raise an exception if called with a non-existent username.

Python pwd 模块提供对getpwnam(3)POSIX API 的访问,该 API 可用于通过用户名获取特定用户的主目录,以及确定用户名是否有效。 pwd.getpwnam如果使用不存在的用户名调用将引发异常。

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.

起初,似乎可以通过跨平台的方式实现相同的结果os.path.expanduser('~username')。但是,对于 Windows XP 上的 Python 2.6,对于不存在的用户名,这实际上不会导致失败。此外,在 Windows XP 上的 Python 2.5 上,即使对于有效用户,它似乎也失败了。

Can this information be obtained reliably on Windows? How?

能否在 Windows 上可靠地获取此信息?如何?

采纳答案by Nas Banov

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

阅读2.6 文档表明它os.path.expanduser()在 Windows上已损坏:

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

在 Windows 上,如果设置了 HOME 和 USERPROFILE,则将使用,否则将使用 HOMEPATH 和 HOMEDRIVE 的组合。通过从上面派生的创建的用户路径中剥离最后一个目录组件来处理初始~user

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]

回答by Adi Roiban

I am new to Windows security... but reading MSDN and some blogs it seems to me that the way MS want us to handle other users specific data is by getting a user token.

我是 Windows 安全的新手……但是阅读 MSDN 和一些博客,在我看来,MS 希望我们处理其他用户特定数据的方式是获取用户令牌。

There used to be a nice wiki of Keith Brown .Net Developers Guide to Windows Security... you can still find it in Google cache for "pluralsight keith.guidebook"

曾经有一个很好的基思布朗维基 .Net Windows 安全开发人员指南......你仍然可以在谷歌缓存中找到它的“pluralsight keith.guidebook”

Case 1: If you don't have the user password:

情况 1:如果您没有用户密码:

For local accounts you can try reading the Windows registry as Nas Banov already suggested and there are some other recipes on SO or the Internet.

对于本地帐户,您可以尝试阅读 Nas Banov 已经建议的 Windows 注册表,并且在 SO 或 Internet 上还有一些其他方法。

I am not sure how various Windows versions behaves for freshly create users ... those which have never performed an interactive session login ... does it automatically creates their registry, home folder and profile data? I have done some tests on Windows XP and those registry keys were not present after creating an local account ... but in this case you can try to guess it based in All Users registry values ... or just fail :)

我不确定各种 Windows 版本对于新创建的用户的行为......那些从未执行过交互式会话登录的用户......它是否会自动创建他们的注册表、主文件夹和配置文件数据?我已经在 Windows XP 上进行了一些测试,但在创建本地帐户后这些注册表项不存在……但在这种情况下,您可以尝试根据“所有用户”注册表值来猜测它……或者只是失败:)

For desktop applications, when the application is running as a logged in user, I am using something like this to get the home folder.... and to get the equivalent of ~/.local I am using CSIDL_APPDATA, for roaming profiles, or just CSIDL_LOCAL_APPDATA.

对于桌面应用程序,当应用程序以登录用户身份运行时,我使用类似这样的东西来获取主文件夹......并获得等效的 ~/.local 我正在使用 CSIDL_APPDATA,用于漫游配置文件,或只是 CSIDL_LOCAL_APPDATA。

from win32com.shell import shell, shellcon
# See microsoft references for further CSIDL constants
# http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)

Reading Keith Brown article "How To Get A Token For A User" .. you can look for some other ways of getting an user token without a password...

阅读 Keith Brown 文章“如何为用户获取令牌”……您可以寻找其他一些无需密码即可获取用户令牌的方法……

Case 2: If you have the user password:

情况 2:如果您有用户密码:

Reading the MSDN I got the impressing that if I have an user token, I can get its folders by calling something like the code below... but it did not worked for me. (not sure why)

阅读 MSDN 我印象深刻的是,如果我有一个用户令牌,我可以通过调用类似下面的代码来获取它的文件夹......但它对我不起作用。(不知道为什么)

token = win32security.LogonUser(
            username,
            None, # we uses UPN format for username
            password,
            win32security.LOGON32_LOGON_NETWORK,
            win32security.LOGON32_PROVIDER_DEFAULT,
            )
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, token, 0)

This is why I ended up with this code...which is far from being perfect due to the fact that it requires username and password.

这就是为什么我最终得到了这个代码......这远非完美,因为它需要用户名和密码。

token = win32security.LogonUser(
            username,
            None, # Here should be the domain ... or just go with default values
            password,
            win32security.LOGON32_LOGON_NETWORK,
            win32security.LOGON32_PROVIDER_DEFAULT,
            )
win32security.ImpersonateLoggedOnUser(token)
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)
win32security.RevertToSelf()


This question is somehow related: How to find the real user home directory using python?

这个问题有点相关:How to find the real user home directory using python?

回答by Wayne Werner

This seems to be only applicable to the current user, but on my (winxp) machine, os.path.expanduser('~')returns my home directory.

这似乎只适用于当前用户,但在我的(winxp)机器上,os.path.expanduser('~')返回我的主目录。

回答by akira

you could go the win32api.GetUserName()(current user only) or win32net.NetUserGetInfo()(any user on any server, localhost included) route. the latter could be a bit slow since it can take some time to get this information back from the OS.

您可以使用win32api.GetUserName()(仅限当前用户)或win32net.NetUserGetInfo()(任何服务器上的任何用户,包括本地主机)路由。后者可能会有点慢,因为从操作系统获取此信息可能需要一些时间。

  import win32net

  def userDir(username):
        return win32net.NetUserGetInfo(None, username, 1).get("home_dir")

alternatively you could expand the environment variable USERPROFILEon windows or HOMEon unix to get the information about the currently logged in user:

或者,您可以USERPROFILE在 Windows 或HOMEunix上扩展环境变量以获取有关当前登录用户的信息:

  def userDir():
      if os.platform.system() == 'Windows':
          return os.environ['USERPROFILE']
      elif os.platform.system() == 'Linux':
          return os.environ['HOME'] 
      else:
          return None