Discussion:
[Tutor] Windows "feature" I don't understand
Clayton Kirkwood
2015-08-03 02:14:33 UTC
Permalink
In a former life, I played the part of a system manager in a number of Unix
environments, which I really liked. Now, I am stuck using Windows and don't
get into the innards much. I ran into a problem in my program, which we have
been discussing, which is windows-caused. I originally set my directory in
my code to /users/Clayton/Pictures by memory that that was the name of the
directory in windows. My code worked using the directory. I then noticed
that my "real" directory as listed by windows explorer was /users/Clayton/My
Pictures. I changed it in my code and nothing works. /users/Clayton/Pictures
doesn't show up in explorer even tho I've set to display hidden files,
system files, etc. I dropped down into dos and lo and behold, Picture exists
but there is no My Pictures. That explains why pictures worked, but I don't
understand the discrepancy for the differences, why My Pictures doesn't
work, etc. My Pictures is not a link in explorer.

Any shed light would be greatly appreciated.

TIA,

Clayton

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Válas Péter
2015-08-03 06:09:56 UTC
Permalink
My "best practice" is to avoid Windows-generated directories and create my
own ones. :-)
They are linked and "pseudo-named" in a really messy way even if you use
English Windows, but the real extended horror begins at different languages
where Windows randomly uses English and translated names. Also, I usually
know better what I need than some of those guys in Redmond. I think
Users\Clayton should be the last point where you use the default structure,
but if it is your own computer, it's even better to leave the whole Users
directory for the playground of Windows and create your own documents
structure. Preferably on another device or partition than location of
operating system. (However, Windows itself allows you to relocate these
directories in the official structure.)

Also, it is wise to define this path at the beginning of your script in
case you want to use it elsewhere.
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
eryksun
2015-08-03 09:26:09 UTC
Permalink
Post by Clayton Kirkwood
get into the innards much. I ran into a problem in my program, which we have
been discussing, which is windows-caused. I originally set my directory in
my code to /users/Clayton/Pictures by memory that that was the name of the
directory in windows. My code worked using the directory. I then noticed
that my "real" directory as listed by windows explorer was
/users/Clayton/My Pictures. I changed it in my code and nothing works.
/users/Clayton/Pictures doesn't show up in explorer even tho I've set to
display hidden files, system files, etc.
"My Pictures" is a localized name. The actual filesystem path in your
case is %USERPROFILE%\Pictures. There should be a hidden file named
desktop.ini in that directory. It defines the shell32 resource ID of
the localized name. If for some reason you need this display string,
you can retrieve it via PyWin32's win32api.LoadString, or via ctypes.
Here's an example of the latter.

rstring.py:

import ctypes
from ctypes import wintypes

user32 = ctypes.WinDLL('user32', use_last_error=True)

def errcheck_bool(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args

user32.LoadStringW.errcheck = errcheck_bool
user32.LoadStringW.argtypes = (wintypes.HINSTANCE,
wintypes.UINT,
wintypes.LPWSTR,
ctypes.c_int)

PWCHAR = ctypes.POINTER(wintypes.WCHAR)

def load_string(hInstance, uID):
resource = PWCHAR()
lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR)
nchar = user32.LoadStringW(hInstance, uID, lpBuffer, 0)
return resource[:nchar]

if __name__ == '__main__':
import os
import sys
if len(sys.argv) != 3:
sys.exit('usage:\n%s dllPath stringId' %
os.path.basename(sys.argv[0]))
hInstance = ctypes.WinDLL(sys.argv[1])._handle
uID = int(sys.argv[2])
print(load_string(hInstance, uID))

For example, here's the contents of the desktop.ini file in Windows 7:

C:\>type C:\Users\Administrator\Pictures\desktop.ini

[.ShellClassInfo]
LocalizedResourceName=@%SystemRoot%\system32\shell32.dll,-21779
InfoTip=@%SystemRoot%\system32\shell32.dll,-12688
IconResource=%SystemRoot%\system32\imageres.dll,-113
IconFile=%SystemRoot%\system32\shell32.dll
IconIndex=-236

And here's what I get for the LocalizedResourceName and InfoTip for a
system configured for U.S. English:

C:\>rstring.py shell32 21779
My Pictures

C:\>rstring.py shell32 12688
Contains digital photos, images, and graphic files.

(In practice, instead of looking for desktop.ini files, a program
should call SHGetLocalizedName to get the module path and resource
ID.)

It's unwise to just assume the location of a shell folder. The
underlying filesystem paths are customizable. Instead, use the API to
get the location of known folders by GUID. For Windows Vista and later
you can call SHGetKnownFolderPath. This function isn't available in
PyWin32, but it does wrap the old SHGetFolderPath function in
win32com.shell.shell. SHGetFolderPath uses the CSIDL_* constants,
which are defined in win32com.shell.shellcon.

Here's a ctypes example that calls SHGetKnownFolderPath to look up the
path for FOLDERID_Pictures. As a bonus I've also included the GUIDs
for several other folders.

import ctypes
from ctypes import wintypes

ole32 = ctypes.OleDLL('ole32')
shell32 = ctypes.OleDLL('shell32')

class GUID(ctypes.Structure):
_fields_ = (('Data1', ctypes.c_ulong),
('Data2', ctypes.c_ushort),
('Data3', ctypes.c_ushort),
('Data4', ctypes.c_char * 8))
def __init__(self, guid_string):
ole32.IIDFromString(guid_string, ctypes.byref(self))

IID = GUID
LPIID = ctypes.POINTER(IID)
LPCOLESTR = wintypes.LPCWSTR
ole32.IIDFromString.argtypes = (LPCOLESTR,
LPIID)

ole32.CoTaskMemFree.restype = None
ole32.CoTaskMemFree.argtypes = (wintypes.LPVOID,)

REFKNOWNFOLDERID = LPIID
shell32.SHGetKnownFolderPath.argtypes = (REFKNOWNFOLDERID,
wintypes.DWORD,
wintypes.HANDLE,
ctypes.POINTER(wintypes.LPWSTR))

def get_known_folder_path(folder_id):
pszPath = wintypes.LPWSTR()
shell32.SHGetKnownFolderPath(ctypes.byref(folder_id),
0, None, ctypes.byref(pszPath))
folder_path = pszPath.value
ole32.CoTaskMemFree(pszPath)
return folder_path

# common
FOLDERID_Public = GUID('{DFDF76A2-C82A-4D63-906A-5644AC457385}')
FOLDERID_PublicDesktop = GUID('{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}')
FOLDERID_PublicDocuments = GUID('{ED4824AF-DCE4-45A8-81E2-FC7965083634}')
FOLDERID_PublicDownloads = GUID('{3D644C9B-1FB8-4f30-9B45-F670235F79C0}')
FOLDERID_PublicMusic = GUID('{3214FAB5-9757-4298-BB61-92A9DEAA44FF}')
FOLDERID_PublicPictures = GUID('{B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5}')
FOLDERID_PublicVideos = GUID('{2400183A-6185-49FB-A2D8-4A392A602BA3}')
FOLDERID_ProgramData = GUID('{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}')
FOLDERID_CommonStartMenu = GUID('{A4115719-D62E-491D-AA7C-E74B8BE3B067}')
FOLDERID_CommonPrograms = GUID('{0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8}')
FOLDERID_CommonStartup = GUID('{82A5EA35-D9CD-47C5-9629-E15D2F714E6E}')
FOLDERID_CommonTemplates = GUID('{B94237E7-57AC-4347-9151-B08C6C32D1F7}')
# user
FOLDERID_Profile = GUID('{5E6C858F-0E22-4760-9AFE-EA3317B67173}')
FOLDERID_Desktop = GUID('{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}')
FOLDERID_Documents = GUID('{FDD39AD0-238F-46AF-ADB4-6C85480369C7}')
FOLDERID_Downloads = GUID('{374DE290-123F-4565-9164-39C4925E467B}')
FOLDERID_Music = GUID('{4BD8D571-6D19-48D3-BE97-422220080E43}')
FOLDERID_Pictures = GUID('{33E28130-4E1E-4676-835A-98395C3BC3BB}')
FOLDERID_Videos = GUID('{18989B1D-99B5-455B-841C-AB7C74E4DDFC}')
FOLDERID_LocalAppData = GUID('{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}')
FOLDERID_LocalAppDataLow = GUID('{A520A1A4-1780-4FF6-BD18-167343C5AF16}')
FOLDERID_RoamingAppData = GUID('{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}')
FOLDERID_StartMenu = GUID('{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}')
FOLDERID_Programs = GUID('{A77F5D77-2E2B-44C3-A6A2-ABA601054A51}')
FOLDERID_Startup = GUID('{B97D20BB-F46A-4C97-BA10-5E3608430854}')
FOLDERID_Templates = GUID('{A63293E8-664E-48DB-A079-DF759E0509F7}')

if __name__ == '__main__':
print(get_known_folder_path(FOLDERID_Pictures))
Post by Clayton Kirkwood
I dropped down into dos and lo and behold,
You probably ran cmd.exe, which is a Win32 console application, not
DOS. The cmd shell makes only limited use of shell32 functionality,
such as calling ShellExecuteEx to open/execute files. (FYI, the
attached console window is hosted by the GUI application conhost.exe.
If you run python.exe from Explorer it's similarly attached to an
instance of conhost.exe, without a running instance of cmd.exe. So
don't assume that console windows in general have anything to do with
cmd.exe.)
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Loading...