如何用Python创建或复制文件夹到Windows AppData目录且能被系统工具正常访问?
兄弟,你这问题我之前踩过一模一样的坑!你碰到的情况大概率是Windows的环境隔离或者路径重定向在搞鬼,咱们一步步拆解解决:
最常见的元凶:Microsoft Store版Python的沙箱隔离
如果你是从微软商店安装的Python,那问题基本出在这——商店版Python有Windows沙箱隔离机制,它会偷偷把你对%APPDATA%的访问重定向到一个专属的隔离文件夹里,比如C:\Users\<你的用户名>\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.x_qbz5n2kfra8p0\LocalCache\Roaming。
这时候你在Python里用os.path.exists能看到文件夹,那是因为它看的是隔离后的路径;而资源管理器、PowerShell访问的是你真实的%APPDATA%\Roaming目录,自然找不到。
解决办法:
要么换成Python官网下载的官方安装版(别选商店版),要么手动指定真实的AppData路径来操作:
import os import shutil # 获取真实的用户AppData/Roaming路径 real_appdata = os.path.expandvars("%APPDATA%") target_folder = os.path.join(real_appdata, "MyApp") # 创建目标文件夹(已存在也不会报错) os.makedirs(target_folder, exist_ok=True) # 复制文件/文件夹的示例 shutil.copy2("你的源文件路径", target_folder) # 如果是复制整个文件夹用这个 # shutil.copytree("源文件夹路径", os.path.join(target_folder, "子文件夹名"))
次常见情况:32位Python在64位系统的重定向
如果你的Python是32位版本,运行在64位Windows上,可能会触发Wow64文件系统重定向(虽然AppData目录一般不会被重定向,但保险起见可以处理)。我们可以临时关闭重定向再操作:
import ctypes import os import shutil # 调用Windows API关闭Wow64重定向 kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) old_redir_state = ctypes.c_long() kernel32.Wow64DisableWow64FsRedirection(ctypes.byref(old_redir_state)) try: real_appdata = os.path.expandvars("%APPDATA%") target_folder = os.path.join(real_appdata, "MyApp") os.makedirs(target_folder, exist_ok=True) # 这里执行你需要的复制/创建操作 shutil.copytree("你的源文件夹路径", os.path.join(target_folder, "子文件夹")) finally: # 一定要恢复重定向,避免影响后续系统操作 kernel32.Wow64RevertWow64FsRedirection(old_redir_state)
小概率情况:文件夹被标记为隐藏/系统属性
如果上面两种情况都不是,那可能是你创建的文件夹被意外标记了隐藏或系统属性,导致系统工具默认不显示。可以手动移除这些属性:
import ctypes from ctypes import wintypes import os # 定义Windows文件属性常量 FILE_ATTRIBUTE_HIDDEN = 0x02 FILE_ATTRIBUTE_SYSTEM = 0x04 def fix_folder_visibility(path): kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # 获取当前文件夹的属性 get_attr = kernel32.GetFileAttributesW get_attr.argtypes = [wintypes.LPCWSTR] get_attr.restype = wintypes.DWORD current_attrs = get_attr(path) if current_attrs == 0xFFFFFFFF: return False # 获取属性失败 # 移除隐藏和系统属性 new_attrs = current_attrs & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) # 应用新属性 set_attr = kernel32.SetFileAttributesW set_attr.argtypes = [wintypes.LPCWSTR, wintypes.DWORD] set_attr.restype = wintypes.BOOL return set_attr(path, new_attrs) != 0 # 创建文件夹后调用修复函数 real_appdata = os.path.expandvars("%APPDATA%") target_folder = os.path.join(real_appdata, "MyApp") os.makedirs(target_folder, exist_ok=True) fix_folder_visibility(target_folder)
按照上面的方法操作后,再打开资源管理器或PowerShell,肯定能看到你创建的MyApp文件夹了,再也不用靠subprocess调用PowerShell这种hack方法啦!
备注:内容来源于stack exchange,提问作者Lucian Thorr

