On Wed, Jan 10, 2018 at 12:59 PM, Albert-Jan Roskam <sjeik_ap...@hotmail.com> wrote: > > I tried: >>>> from os.path import _getfullpathname >>>> _getfullpathname(r"H:") > 'h:\\path\\to\\folder' >>>> import os >>>> os.getcwd() > 'h:\\path\\to\\folder' > > I expected h:\ to be \\server\share\foo.
You called _getfullpathname (WinAPI GetFullPathName), not _getfinalpathname (WinAPI GetFinalPathNameByHandle). GetFullPathName works on the path as a string without touching the filesystem. GetFinalPathNameByHandle reconstructs a path when given a handle to a file or directory. > The fact that the current working directory was returned was even more > unexpected. "H:" or "H:relative/path" is relative to the working directory on drive H:. The process only has one working directory, but GetFullPathName also checks for environment variables such as "=H:". The C runtime's _chdir function sets these magic variables, as does Python's os.chdir function (we don't call C _chdir). WinAPI SetCurrentDirectory does not set them. For example: >>> os.chdir('Z:/Temp') >>> win32api.GetEnvironmentVariable('=Z:') 'Z:\\Temp' >>> os.path._getfullpathname('Z:relative') 'Z:\\Temp\\relative' > Why would anybody *want* the drive letters? They are only useful because (a) > they save on > keystrokes (b) they bypass the annoying limitation of the cd command on > windows, ie. it > does not work with UNC paths. Windows itself has no problem using a UNC path as the working directory. That's a limit of the CMD shell. SUBST drives can be used to access long paths. Since the substitution occurs in the kernel, it avoids the MAX_PATH 260-character limit. Of course, you can also use junctions and symlinks to access long paths, or in Windows 10 simply enable long-path support. > I know net use, pushd, subst. I use 'net use' for more or less permanent > drives and > pushd/popd to get a temporary drive, available letter (cd nuisance). `net.exe use` and CMD's PUSHD command (with a UNC path) both call WinAPI WNetAddConnection2 to create a mapped network drive. The difference is that net.exe can supply alternate credentials and create a persistent mapping, while PUSHD uses the current user's credentials and creates a non-persistent mapping. If your account gets logged on with a UAC split token, the standard and elevated tokens actually have separate logon sessions with separate local-device mappings. You can enable a policy to link the two logon sessions. Set a DWORD value of 1 named "EnableLinkedConnections" in the key "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System", and reboot. subst.exe creates substitute paths using WinAPI DefineDosDevice. Unlike the WNet API, this function doesn't use MPR (multiple provider router) to create a direct link for the network provider (e.g. \Device\LanmanRedirectory); doesn't create a linked connection when EnableLinkedConnections is defined; and can't create a persistent drive with stored credentials (though you can use an account logon script for this). On the plus side, a drive mapped via subst.exe can target any path. > Interesting code! I have used the following, which uses SHGetFolderPath, ie. > without 'Known'. > from win32com.shell import shell, shellcon > desktop = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, 0, 0) SHGetFolderPath is usually fine, but still, it's outdated and deprecated. win32com.shell doesn't wrap SHGetKnownFolderPath for some reason, but you can still use the new known-folder API without ctypes. Just create a KnownFolderManager instance. For example: import pythoncom from win32com.shell import shell kfmgr = pythoncom.CoCreateInstance(shell.CLSID_KnownFolderManager, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IKnownFolderManager) desktop_path = kfmgr.GetFolder(shell.FOLDERID_Desktop).GetPath() This doesn't work as conveniently for getting known folders of other users. While the high-level SHGetKnownFolderPath function takes care of loading the user profile and impersonating, we have to do this ourselves when using a KnownFolderManager instance. That said, to correct my previous post, you have to be logged on with SeTcbPrivilege access (e.g. a SYSTEM service) to get and set other users' known folders without their password. (If you have the password you can use a regular logon instead of an S4U logon, and that works fine.) > Working with ctypes.wintypes is quite complex! I wouldn't say ctypes is complex in general. But calling LsaLogonUser is complex due to all of the structs that include variable-sized buffers. And working with COM via ctypes is also complex, which is why comtypes exists. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor