75
75
except ImportError:
76
76
has_win32api = False
78
# pulling in win32com.shell is a bit of overhead, and normally we don't need
79
# it as ctypes is preferred and common. lazy_imports and "optional"
80
# modules don't work well, so we do our own lazy thing...
81
has_win32com_shell = None # Set to True or False once we know for sure...
79
83
# Special Win32 API constants
80
84
# Handles of std streams
119
124
return (defaultx, defaulty)
127
def _get_sh_special_folder_path(csidl):
128
"""Call SHGetSpecialFolderPathW if available, or return None.
130
Result is always unicode (or None).
134
SHGetSpecialFolderPath = \
135
ctypes.windll.shell32.SHGetSpecialFolderPathW
136
except AttributeError:
139
buf = ctypes.create_unicode_buffer(MAX_PATH)
140
if SHGetSpecialFolderPath(None,buf,csidl,0):
143
global has_win32com_shell
144
if has_win32com_shell is None:
146
from win32com.shell import shell
147
has_win32com_shell = True
149
has_win32com_shell = False
150
if has_win32com_shell:
151
# still need to bind the name locally, but this is fast.
152
from win32com.shell import shell
154
return shell.SHGetSpecialFolderPath(0, csidl, 0)
156
# possibly E_NOTIMPL meaning we can't load the function pointer,
157
# or E_FAIL meaning the function failed - regardless, just ignore it
122
162
def get_appdata_location():
123
163
"""Return Application Data location.
124
164
Return None if we cannot obtain location.
126
Returned value can be unicode or plain sring.
166
Windows defines two 'Application Data' folders per user - a 'roaming'
167
one that moves with the user as they logon to different machines, and
168
a 'local' one that stays local to the machine. This returns the 'roaming'
169
directory, and thus is suitable for storing user-preferences, etc.
171
Returned value can be unicode or plain string.
127
172
To convert plain string to unicode use
128
173
s.decode(bzrlib.user_encoding)
174
(XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
132
SHGetSpecialFolderPath = \
133
ctypes.windll.shell32.SHGetSpecialFolderPathW
134
except AttributeError:
137
buf = ctypes.create_unicode_buffer(MAX_PATH)
138
if SHGetSpecialFolderPath(None,buf,CSIDL_APPDATA,0):
176
appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
140
179
# from env variable
141
180
appdata = os.environ.get('APPDATA')
194
def get_local_appdata_location():
195
"""Return Local Application Data location.
196
Return the same as get_appdata_location() if we cannot obtain location.
198
Windows defines two 'Application Data' folders per user - a 'roaming'
199
one that moves with the user as they logon to different machines, and
200
a 'local' one that stays local to the machine. This returns the 'local'
201
directory, and thus is suitable for caches, temp files and other things
202
which don't need to move with the user.
204
Returned value can be unicode or plain string.
205
To convert plain string to unicode use
206
s.decode(bzrlib.user_encoding)
207
(XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
209
local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
212
# Vista supplies LOCALAPPDATA, but XP and earlier do not.
213
local = os.environ.get('LOCALAPPDATA')
216
return get_appdata_location()
155
219
def get_home_location():
156
220
"""Return user's home location.
157
221
Assume on win32 it's the <My Documents> folder.
162
226
To convert plain string to unicode use
163
227
s.decode(bzrlib.user_encoding)
167
SHGetSpecialFolderPath = \
168
ctypes.windll.shell32.SHGetSpecialFolderPathW
169
except AttributeError:
172
buf = ctypes.create_unicode_buffer(MAX_PATH)
173
if SHGetSpecialFolderPath(None,buf,CSIDL_PERSONAL,0):
229
home = _get_sh_special_folder_path(CSIDL_PERSONAL)
175
232
# try for HOME env variable
176
233
home = os.path.expanduser('~')