Windows系统中Unix模块pwd.getpwuid的等效替代方案是什么?
Windows下替代Unix
pwd.getpwuid() 的方案 由于pwd模块是Unix专属,Windows环境下可以通过以下两种方式实现获取文件所有者名称的等效功能:
方法1:使用pywin32库(第三方库,简单易用)
需要先安装pywin32:
pip install pywin32
通过win32api和win32security模块获取文件所有者:
import win32api import win32security def get_file_owner_name(file_path): # 获取文件的安全信息,仅请求所有者相关数据 sd = win32security.GetFileSecurity(file_path, win32security.OWNER_SECURITY_INFORMATION) # 提取所有者的SID(安全标识符) owner_sid = sd.GetSecurityDescriptorOwner() # 将SID转换为可读的账户名(格式:域名\用户名) name, domain, _ = win32security.LookupAccountSid(None, owner_sid) return f"{domain}\\{name}" # 调用示例 file_owner_name = get_file_owner_name("C:\\example.txt") print(file_owner_name)
方法2:使用ctypes调用Windows原生API(无需额外依赖)
如果不想安装第三方库,可以直接用Python自带的ctypes调用Windows系统API:
import ctypes from ctypes import wintypes # 加载Windows系统库 advapi32 = ctypes.WinDLL('advapi32', use_last_error=True) kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # 定义安全描述符结构 class SECURITY_DESCRIPTOR(ctypes.Structure): _fields_ = [ ('Revision', wintypes.BYTE), ('Sbz1', wintypes.BYTE), ('Control', wintypes.DWORD), ('Owner', wintypes.LPVOID), ('Group', wintypes.LPVOID), ('Sacl', wintypes.LPVOID), ('Dacl', wintypes.LPVOID) ] # 配置API函数的参数和返回值类型 advapi32.GetFileSecurityW.argtypes = [wintypes.LPCWSTR, wintypes.DWORD, wintypes.LPVOID, wintypes.DWORD, wintypes.LPDWORD] advapi32.GetFileSecurityW.restype = wintypes.BOOL advapi32.GetSecurityDescriptorOwner.argtypes = [ctypes.POINTER(SECURITY_DESCRIPTOR), ctypes.POINTER(wintypes.LPVOID), ctypes.POINTER(wintypes.BOOL)] advapi32.GetSecurityDescriptorOwner.restype = wintypes.BOOL advapi32.LookupAccountSidW.argtypes = [wintypes.LPCWSTR, wintypes.LPVOID, wintypes.LPWSTR, wintypes.LPDWORD, wintypes.LPWSTR, wintypes.LPDWORD, wintypes.LPDWORD] advapi32.LookupAccountSidW.restype = wintypes.BOOL kernel32.LocalFree.argtypes = [wintypes.LPVOID] kernel32.LocalFree.restype = wintypes.LPVOID OWNER_SECURITY_INFORMATION = 0x00000001 def get_file_owner_name(file_path): # 获取所需安全描述符的内存大小 buf_size = wintypes.DWORD(0) advapi32.GetFileSecurityW(file_path, OWNER_SECURITY_INFORMATION, None, 0, ctypes.byref(buf_size)) # 分配内存存储安全描述符 sd_buf = ctypes.create_string_buffer(buf_size.value) if not advapi32.GetFileSecurityW(file_path, OWNER_SECURITY_INFORMATION, sd_buf, buf_size, ctypes.byref(buf_size)): raise ctypes.WinError(ctypes.get_last_error()) # 解析安全描述符,提取所有者SID sd = ctypes.cast(sd_buf, ctypes.POINTER(SECURITY_DESCRIPTOR)) owner_sid = wintypes.LPVOID() if not advapi32.GetSecurityDescriptorOwner(sd, ctypes.byref(owner_sid), None): raise ctypes.WinError(ctypes.get_last_error()) # 获取账户名和域名的长度 name_len = wintypes.DWORD(0) domain_len = wintypes.DWORD(0) advapi32.LookupAccountSidW(None, owner_sid, None, ctypes.byref(name_len), None, ctypes.byref(domain_len), None) # 分配内存存储账户名和域名 name_buf = ctypes.create_unicode_buffer(name_len.value) domain_buf = ctypes.create_unicode_buffer(domain_len.value) if not advapi32.LookupAccountSidW(None, owner_sid, name_buf, ctypes.byref(name_len), domain_buf, ctypes.byref(domain_len), None): raise ctypes.WinError(ctypes.get_last_error()) return f"{domain_buf.value}\\{name_buf.value}" # 调用示例 file_owner_name = get_file_owner_name("C:\\example.txt") print(file_owner_name)
补充说明
Windows系统没有Unix意义上的UID,用户身份通过**SID(安全标识符)**唯一标识。如果你的原逻辑是通过文件的UID获取所有者,直接通过文件路径获取SID再转换为名称是更贴合Windows环境的实现方式。
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

