70
70
except ImportError:
71
71
has_win32file = False
73
# pulling in win32com.shell is a bit of overhead, and normally we don't need
74
# it as ctypes is preferred and common. lazy_imports and "optional"
75
# modules don't work well, so we do our own lazy thing...
76
has_win32com_shell = None # Set to True or False once we know for sure...
74
78
# Special Win32 API constants
75
79
# Handles of std streams
114
119
return (defaultx, defaulty)
122
def _get_sh_special_folder_path(csidl):
123
"""Call SHGetSpecialFolderPathW if available, or return None.
125
Result is always unicode (or None).
129
SHGetSpecialFolderPath = \
130
ctypes.windll.shell32.SHGetSpecialFolderPathW
131
except AttributeError:
134
buf = ctypes.create_unicode_buffer(MAX_PATH)
135
if SHGetSpecialFolderPath(None,buf,csidl,0):
138
global has_win32com_shell
139
if has_win32com_shell is None:
141
from win32com.shell import shell
142
has_win32com_shell = True
144
has_win32com_shell = False
145
if has_win32com_shell:
146
# still need to bind the name locally, but this is fast.
147
from win32com.shell import shell
149
return shell.SHGetSpecialFolderPath(0, csidl, 0)
151
# possibly E_NOTIMPL meaning we can't load the function pointer,
152
# or E_FAIL meaning the function failed - regardless, just ignore it
117
157
def get_appdata_location():
118
158
"""Return Application Data location.
119
159
Return None if we cannot obtain location.
121
Returned value can be unicode or plain sring.
161
Windows defines two 'Application Data' folders per user - a 'roaming'
162
one that moves with the user as they logon to different machines, and
163
a 'local' one that stays local to the machine. This returns the 'roaming'
164
directory, and thus is suitable for storing user-preferences, etc.
166
Returned value can be unicode or plain string.
122
167
To convert plain string to unicode use
123
168
s.decode(bzrlib.user_encoding)
127
SHGetSpecialFolderPath = \
128
ctypes.windll.shell32.SHGetSpecialFolderPathW
129
except AttributeError:
132
buf = ctypes.create_unicode_buffer(MAX_PATH)
133
if SHGetSpecialFolderPath(None,buf,CSIDL_APPDATA,0):
170
appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
135
173
# from env variable
136
174
appdata = os.environ.get('APPDATA')
188
def get_local_appdata_location():
189
"""Return Local Application Data location.
190
Return the same as get_appdata_location() if we cannot obtain location.
192
Windows defines two 'Application Data' folders per user - a 'roaming'
193
one that moves with the user as they logon to different machines, and
194
a 'local' one that stays local to the machine. This returns the 'local'
195
directory, and thus is suitable for caches, temp files and other things
196
which don't need to move with the user.
198
Returned value can be unicode or plain string.
199
To convert plain string to unicode use
200
s.decode(bzrlib.user_encoding)
202
local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
205
# Vista supplies LOCALAPPDATA, but XP and earlier do not.
206
local = os.environ.get('LOCALAPPDATA')
209
return get_appdata_location()
150
212
def get_home_location():
151
213
"""Return user's home location.
152
214
Assume on win32 it's the <My Documents> folder.
157
219
To convert plain string to unicode use
158
220
s.decode(bzrlib.user_encoding)
162
SHGetSpecialFolderPath = \
163
ctypes.windll.shell32.SHGetSpecialFolderPathW
164
except AttributeError:
167
buf = ctypes.create_unicode_buffer(MAX_PATH)
168
if SHGetSpecialFolderPath(None,buf,CSIDL_PERSONAL,0):
222
home = _get_sh_special_folder_path(CSIDL_PERSONAL)
170
225
# try for HOME env variable
171
226
home = os.path.expanduser('~')