Windows下os.access异常返回True,求替代的路径权限校验库
Windows 路径权限检查替代方案(针对
os.access()失效问题) 问题描述
在Windows环境下使用os.access()检查程序执行者对某路径的权限时,始终返回True,不符合预期。现编写了一个验证文件/目录读取权限的方法(代码如下),希望找到类似Linux下os.access()功能的简化库来实现Windows路径权限验证:
def _readable_path(abs_path: Path, uname: str): # Existing validation try: exists = abs_path.exists() except PermissionError as e: return build_not_path_access(abs_path, uname, e) except Exception as e: return build_general_path_access(abs_path, uname, e) if not exists: return build_file_not_found(abs_path) # Reading perm check try: security_descriptor = win32security.GetFileSecurity( str(abs_path), win32security.DACL_SECURITY_INFORMATION ) except win32security.error as e: if e.winerror == 5: # Not reading perms return False return build_general_path_access(abs_path, uname, e) return True
可行的简化方案
1. 基于pywin32封装精准权限检查
你已经在用pywin32的win32security模块,可以直接用它的AccessCheck接口做精准权限判断,比单纯捕获错误更可靠,封装后能替代os.access()的功能:
import win32security import win32api import win32file from pathlib import Path def has_read_access(abs_path: Path) -> bool: path_str = str(abs_path) try: # 获取当前进程的用户令牌 token = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_QUERY) user_sid, _ = win32security.GetTokenInformation(token, win32security.TokenUser) # 获取目标路径的安全描述符 sd = win32security.GetFileSecurity(path_str, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl() # 定义要验证的读取权限 desired_access = win32file.GENERIC_READ # 执行权限检查 access_granted, _ = win32security.AccessCheck( sd, user_sid, desired_access, None, None, None, None ) return access_granted except win32security.error as e: if e.winerror == 5: # 明确权限不足 return False return False
2. 直接尝试操作(无额外库依赖)
Windows权限模型复杂(含继承权限、用户组权限、UAC虚拟化等),os.access()失效正是因为没考虑这些场景。更可靠的方式是跳过预检查,直接尝试执行目标操作,捕获PermissionError:
from pathlib import Path def is_readable(abs_path: Path) -> bool: if not abs_path.exists(): return False try: if abs_path.is_file(): # 尝试打开文件验证读取权限 with open(abs_path, 'r'): pass elif abs_path.is_dir(): # 尝试读取目录内容验证权限 next(abs_path.iterdir()) return True except PermissionError: return False except StopIteration: # 空目录,说明有权限读取 return True except Exception: return False
这种方式不需要额外依赖,且结果更贴近实际操作的权限情况,避免预检查和实际操作间的权限变化问题。
内容的提问来源于stack exchange,提问作者user27330410
相关产品推荐
相关产品推荐

