114
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
117
162
def get_appdata_location():
118
163
"""Return Application Data location.
119
164
Return None if we cannot obtain location.
121
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.
122
172
To convert plain string to unicode use
123
s.decode(bzrlib.user_encoding)
173
s.decode(osutils.get_user_encoding())
174
(XXX - but see bug 262874, which asserts the correct encoding is 'mbcs')
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):
176
appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
135
179
# from env variable
136
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()
150
219
def get_home_location():
151
220
"""Return user's home location.
152
221
Assume on win32 it's the <My Documents> folder.
156
225
Returned value can be unicode or plain sring.
157
226
To convert plain string to unicode use
158
s.decode(bzrlib.user_encoding)
227
s.decode(osutils.get_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):
229
home = _get_sh_special_folder_path(CSIDL_PERSONAL)
170
232
# try for HOME env variable
171
233
home = os.path.expanduser('~')
202
264
return os.environ.get('USERNAME', None)
267
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
268
# computer or the cluster associated with the local computer."
269
_WIN32_ComputerNameDnsHostname = 1
205
271
def get_host_name():
206
272
"""Return host machine name.
207
273
If name cannot be obtained return None.
209
Returned value can be unicode or plain sring.
210
To convert plain string to unicode use
211
s.decode(bzrlib.user_encoding)
275
:return: A unicode string representing the host name. On win98, this may be
276
a plain string as win32 api doesn't support unicode.
280
return win32api.GetComputerNameEx(_WIN32_ComputerNameDnsHostname)
281
except (NotImplementedError, win32api.error):
282
# NotImplemented will happen on win9x...
215
286
kernel32 = ctypes.windll.kernel32
216
GetComputerName = getattr(kernel32, 'GetComputerName'+suffix)
217
287
except AttributeError:
288
pass # Missing the module we need
220
290
buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
221
291
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
222
if GetComputerName(buf, ctypes.byref(n)):
224
# otherwise try env variables
225
return os.environ.get('COMPUTERNAME', None)
293
# Try GetComputerNameEx which gives a proper Unicode hostname
294
GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
296
if (GetComputerNameEx is not None
297
and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
298
buf, ctypes.byref(n))):
301
# Try GetComputerName in case GetComputerNameEx wasn't found
302
# It returns the NETBIOS name, which isn't as good, but still ok.
303
# The first GetComputerNameEx might have changed 'n', so reset it
304
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
305
GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
307
if (GetComputerName is not None
308
and GetComputerName(buf, ctypes.byref(n))):
310
# otherwise try env variables, which will be 'mbcs' encoded
311
# on Windows (Python doesn't expose the native win32 unicode environment)
313
# http://msdn.microsoft.com/en-us/library/aa246807.aspx
314
# environment variables should always be encoded in 'mbcs'.
316
return os.environ['COMPUTERNAME'].decode("mbcs")
228
321
def _ensure_unicode(s):
322
from bzrlib import osutils
229
323
if s and type(s) != unicode:
231
s = s.decode(bzrlib.user_encoding)
324
from bzrlib import osutils
325
s = s.decode(osutils.get_user_encoding())
235
329
def get_appdata_location_unicode():
236
330
return _ensure_unicode(get_appdata_location())