我希望我的应用程序存储一些数据供所有用户访问。使用Python,我如何找到数据的位置?
答案 0 :(得分:39)
如果您不想为winpaths等第三方模块添加依赖项,我建议您使用Windows中已有的环境变量:
具体而言,您可能希望ALLUSERSPROFILE
获取公共用户配置文件文件夹的位置,该文件夹位于Application Data目录所在的位置。
例如:
C:\> python -c "import os; print os.environ['ALLUSERSPROFILE']"
C:\Documents and Settings\All Users
编辑:看看winpaths模块,它正在使用ctypes,所以如果你只想使用代码的相关部分而不安装winpath,你可以使用它(显然为了简洁省略了一些错误检查) )。
import ctypes
from ctypes import wintypes, windll
CSIDL_COMMON_APPDATA = 35
_SHGetFolderPath = windll.shell32.SHGetFolderPathW
_SHGetFolderPath.argtypes = [wintypes.HWND,
ctypes.c_int,
wintypes.HANDLE,
wintypes.DWORD, wintypes.LPCWSTR]
path_buf = wintypes.create_unicode_buffer(wintypes.MAX_PATH)
result = _SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, 0, path_buf)
print path_buf.value
示例运行:
C:\> python get_common_appdata.py
C:\Documents and Settings\All Users\Application Data
答案 1 :(得分:13)
来自http://snipplr.com/view.php?codeview&id=7354
homedir = os.path.expanduser('~')
# ...works on at least windows and linux.
# In windows it points to the user's folder
# (the one directly under Documents and Settings, not My Documents)
# In windows, you can choose to care about local versus roaming profiles.
# You can fetch the current user's through PyWin32.
#
# For example, to ask for the roaming 'Application Data' directory:
# (CSIDL_APPDATA asks for the roaming, CSIDL_LOCAL_APPDATA for the local one)
# (See microsoft references for further CSIDL constants)
try:
from win32com.shell import shellcon, shell
homedir = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
except ImportError: # quick semi-nasty fallback for non-windows/win32com case
homedir = os.path.expanduser("~")
要获取所有用户的app-data目录,而不是当前用户,只需使用shellcon.CSIDL_COMMON_APPDATA
代替shellcon.CSIDL_APPDATA
。
答案 2 :(得分:10)
看看http://ginstrom.com/code/winpaths.html。这是一个简单的模块,可以检索Windows文件夹信息。该模块实现get_common_appdata
以获取所有用户的App Data文件夹。
答案 3 :(得分:3)
由于与非美国版本的Windows和Vista不兼容而删除了之前的答案。
编辑:要扩展Out Into Space的答案,你可以使用
winpaths.get_common_appdata
功能。您可以使用easy_install winpaths
或访问pypi页面http://pypi.python.org/pypi/winpaths/并下载.exe安装程序来获取winpath。
答案 4 :(得分:3)
您可以使用os.environ
模块中的os
字典访问所有操作系统环境变量。但是,选择从该字典中使用哪个键可能会很棘手。特别是,在使用这些路径时,您应该了解Windows的国际化(即非英语)版本。
os.environ['ALLUSERSPROFILE']
应该为您提供计算机上所有用户的根目录,但在此之后请注意不要像“应用程序数据”那样硬编码子目录名称,因为这些目录在非英语版本中不存在的Windows。就此而言,您可能希望对可以设置ALLUSERSPROFILE环境变量的Windows版本进行一些研究(我不知道自己 - 它可能是通用的)。
我的XP机器有一个COMMONAPPDATA环境变量,它指向All Users \ Application Data文件夹,但我的Win2K3系统没有这个环境变量。
答案 5 :(得分:1)
由于不推荐SHGetFolderPath,您还可以在Vista及更高版本中使用SHGetKnownFolderPath。这也让您查找比SHGetFolderPath更多的路径。这是一个精简的示例(完整代码available on Gist):
import ctypes, sys
from ctypes import windll, wintypes
from uuid import UUID
class GUID(ctypes.Structure): # [1]
_fields_ = [
("Data1", wintypes.DWORD),
("Data2", wintypes.WORD),
("Data3", wintypes.WORD),
("Data4", wintypes.BYTE * 8)
]
def __init__(self, uuid_):
ctypes.Structure.__init__(self)
self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid_.fields
for i in range(2, 8):
self.Data4[i] = rest>>(8 - i - 1)*8 & 0xff
class FOLDERID: # [2]
LocalAppData = UUID('{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}')
LocalAppDataLow = UUID('{A520A1A4-1780-4FF6-BD18-167343C5AF16}')
RoamingAppData = UUID('{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}')
class UserHandle: # [3]
current = wintypes.HANDLE(0)
common = wintypes.HANDLE(-1)
_CoTaskMemFree = windll.ole32.CoTaskMemFree # [4]
_CoTaskMemFree.restype= None
_CoTaskMemFree.argtypes = [ctypes.c_void_p]
_SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath # [5] [3]
_SHGetKnownFolderPath.argtypes = [
ctypes.POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)
]
class PathNotFoundException(Exception): pass
def get_path(folderid, user_handle=UserHandle.common):
fid = GUID(folderid)
pPath = ctypes.c_wchar_p()
S_OK = 0
if _SHGetKnownFolderPath(ctypes.byref(fid), 0, user_handle, ctypes.byref(pPath)) != S_OK:
raise PathNotFoundException()
path = pPath.value
_CoTaskMemFree(pPath)
return path
common_data_folder = get_path(FOLDERID.RoamingAppData)
# [1] http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx
# [2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457.aspx
# [3] http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188.aspx
# [4] http://msdn.microsoft.com/en-us/library/windows/desktop/ms680722.aspx
# [5] http://www.themacaque.com/?p=954