Python windows my documents

Finding the user’s «My Documents» path

I have this small program and it needs to create a small .txt file in their ‘My Documents’ Folder. Here’s the code I have for that:

textfile=open('C:\Users\MYNAME\Documents','w') lines=['stuff goes here'] textfile.writelines(lines) textfile.close() 

3 Answers 3

This works on both Unix and Windows, according to the docs.

Edit: forward slash due to Sven’s comment.

Better use a forward slash in the path: ‘~/filename’ . Otherwise, you will get unexpected results for things like ‘~\name’ , where the \n will be replaced by a newline character.

On Windows a os.path.expanduser(‘~/filename’) call results in something like ‘C:\\Documents and Settings\\/filename’ which is not the path of something in the user’s My Documents folder.

Note that this does not work if the user has moved their My Documents folder so that it no longer sits under ~ (eg, if it’s on a network share, or a different drive).

this doesn’t work. what you need is df = shell.SHGetDesktopFolder() pidl = df.ParseDisplayName(0, None, «::<450d8fba-ad25-11d0-98a8-0800361b1103>«)[1] mydocs = shell.SHGetPathFromIDList(pidl)

This works without any extra libs:

import ctypes.wintypes CSIDL_PERSONAL = 5 # My Documents SHGFP_TYPE_CURRENT = 0 # Get current, not default value buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf) print(buf.value) 

Also works if documents location and/or default save location is changed by user.

This answer is quite similar to stackoverflow.com/a/3859336/1543290 — however they defined SHGFP_TYPE_CURRENT= 0 # Want current, not default value instead of this answer’s SHGFP_TYPE_CURRENT = 1 # Get current, not default value ! Which is true? According to stackoverflow.com/a/23852297/1543290 , it seems that 0 is correct

@Zvika it is not right or wrong. It depends on what you need. If you need current value, use 1, if default, use 0. If the location is changed by the user then obviously the current value is more essential.

I want to use current and not default value Which value is right for this? According to this answer’s code comment — 1 , according to the other answer — 0

Use shell32 = ctypes.OleDLL(‘shell32’) . Using windll (1) doesn’t check the HRESULT code and (2) leaves you at the mercy of whatever library has set for restype , argtypes , and errcheck for windll.shell32.SHGetFolderPathW . The entire idea of the cdll , windll , and oledll loaders was bad from the start.

On Windows, you can use something similar what is shown in the accepted answer to the question: Python, get windows special folders for currently logged-in user.

For the My Documents folder path, use shellcon.CSIDL_PERSONAL in the shell.SHGetFolderPath() function call instead of shellcon.CSIDL_MYPICTURES .

So, assuming you have the PyWin32 extensions 1 installed, this might work (see caveat in Update section below):

>>> from win32com.shell import shell, shellcon >>> shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0) u'' 

Update: I just read something that said that CSIDL_PERSONAL won’t return the correct folder if the user has changed the default save folder in the Win7 Documents library. This is referring to what you can do in library’s Properties dialog:

screenshot of library properties dialog

The checkmark means that the path is set as the default save location.

I currently am unware of a way to call the SHLoadLibraryFromKnownFolder() function through PyWin32 (there currently isn’t a shell.SHLoadLibraryFromKnownFolder . However it should be possible to do so using the ctypes module.

Источник

Как узнать, где находится папка documents с помощью python?

Мне надо что-бы программа автоматически находила путь к папке Documents и записывала путь в переменную user. Как мне это сделать? Нужно, чтобы находило именно путь, а не имя пользователя.

3 ответа 3

Можно получить из реестра:

from winreg import * aReg = ConnectRegistry(None, HKEY_CURRENT_USER) aKey = OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") name = QueryValueEx(aKey, 'Personal')[0] print(name) 

Как по мне, то можно и так (меньше кода/более читаемый):

import os user = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Documents') 

Можно получить из WinAPI функции SHGetSpecialFolderPathW :

import ctypes from ctypes.wintypes import MAX_PATH CSIDL_PERSONAL = 5 shell32 = ctypes.windll.shell32 buf = ctypes.create_unicode_buffer(MAX_PATH + 1) shell32.SHGetSpecialFolderPathW(None, buf, CSIDL_PERSONAL, False) print(buf.value) 

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.7.21.43541

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

How to get Windows’ special folders for currently logged-in user?

How can I get Windows special folders like My Documents , Desktop , etc. from my Python script? Do I need win32 extensions? It must work on Windows 2000 to Windows 7.

5 Answers 5

Should you wish to do it without the win32 extensions, you can use ctypes to call SHGetFolderPath:

>>> import ctypes.wintypes >>> CSIDL_PERSONAL= 5 # My Documents >>> SHGFP_TYPE_CURRENT= 0 # Want current, not default value >>> buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH) >>> ctypes.windll.shell32.SHGetFolderPathW(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, buf) 0 >>> buf.value u'C:\\Documents and Settings\\User\\My Documents' 

Your code (also) illustrates one of the limitations of using ctypes instead of the win32 extensions, namely the fact that the former doesn’t supply any of the often needed Window’s constants like those defined in win32com.shellcon — so one has to look-up their values and add each of them manually.

Nice solution. And working on my Windows 8. However, the MS Doc (msdn.microsoft.com/en-us/library/bb762181%28VS.85%29.aspx) says that it’s deprecated . I’m not sure what are the implications.

By the way, I had to do ctypes.windll.shell32.SHGetFolderPathW(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, buf) twice. The first time I got error code -2147024890 .

Regarding deprecated : The SHGetKnownFolderPath is much more cumbersome to use, so I would use win32com in that case. Using the answer here for now, to keep down my dependencies :).

You can do it with the pywin32 extensions:

from win32com.shell import shell, shellcon print shell.SHGetFolderPath(0, shellcon.CSIDL_MYPICTURES, None, 0) # prints something like C:\Documents and Settings\Username\My Documents\My Pictures # (Unicode object) 

Check shellcon.CSIDL_xxx for other possible folders.

I think using pywin32 is the best way. Else you’d have to use ctypes to access the SHGetFolderPath function somehow (other solutions might be possible but these are the ones I know).

@Primoz: I don’t know what the abbreviations mean, but all *con modules in the pywin32 package are autogenerated from Windows header files and only contain definitions. The win32com.shell module contains functions from shell32.dll.

The docs mention constants SHGFP_TYPE_CURRENT and SHGFP_TYPE_DEFAULT for the last parameter of SHGetFolderPath() , but these aren’t defined in shellcon for some reason. I wonder why not.

Note that not all shellcon.CSIDL_xxx values are valid on all machines. For example on my machine CSIDL_PERSONAL (5) is valid but CSIDL_MYDOCUMENTS (12) is not. blogs.technet.com/b/heyscriptingguy/archive/2010/06/08/… has a great powershell script for listing all of the special values on a particular machine.

note that My Documents is not retrievable this way. You need to use: df = shell.SHGetDesktopFolder() pidl = df.ParseDisplayName(0, None, «::<450d8fba-ad25-11d0-98a8-0800361b1103>«)[1] mydocs = shell.SHGetPathFromIDList(pidl)

import win32com.client oShell = win32com.client.Dispatch("Wscript.Shell") print oShell.SpecialFolders("Desktop") 

Try winshell (made exactly for this purpose):

import winshell print 'Desktop =>', winshell.desktop () print 'Common Desktop =>', winshell.desktop (1) print 'Application Data =>', winshell.application_data () print 'Common Application Data =>', winshell.application_data (1) print 'Bookmarks =>', winshell.bookmarks () print 'Common Bookmarks =>', winshell.bookmarks (1) print 'Start Menu =>', winshell.start_menu () print 'Common Start Menu =>', winshell.start_menu (1) print 'Programs =>', winshell.programs () print 'Common Programs =>', winshell.programs (1) print 'Startup =>', winshell.startup () print 'Common Startup =>', winshell.startup (1) print 'My Documents =>', winshell.my_documents () print 'Recent =>', winshell.recent () print 'SendTo =>', winshell.sendto () 

Источник

How do you get the exact path to «My Documents»?

In C++ it’s not too hard to get the full pathname to the folder that the shell calls «My Documents» in Windows XP and Windows 7 and «Documents» in Vista; see Get path to My Documents Is there a simple way to do this in Python?

I don’t know much about windows, but isn’t os.environ[‘HOMEPATH’] usually defined on windows systems?

@Mark — Ah, my apologies. It seemed to work on the couple of XP machines that I have access to, and I vaguely recalled it being standard. I guess not!

Irritatingly, Windows does not include the environment variable for this. Attempting to use HOMEPATH or USERPROFILE will burn you, as said directory is not guaranteed to exist in them, either because of Localization or because the System Administrator has moved it.

1 Answer 1

You could use the ctypes module to get the «My Documents» directory:

import ctypes from ctypes.wintypes import MAX_PATH dll = ctypes.windll.shell32 buf = ctypes.create_unicode_buffer(MAX_PATH + 1) if dll.SHGetSpecialFolderPathW(None, buf, 0x0005, False): print(buf.value) else: print("Failure!") 

I’d give a +1, but using the ANSI version may be limiting on directories that use characters outside the default code page.

@Adrian McCarthy, thanks I didn’t notice that. I’ve changed my answer to use the unicode version instead.

I presume the magic constant 0x0005 is CSIDL_PERSONAL. Is the magic constant 300 documented somewhere, or is it just MAX_PATH with some arbitrary padding added?

FWIW, a SHGetSpecialFolderPathW() call returns True if successful, False otherwise, so that can be checked to determine if anything useful was placed in buf.value .

FYI: While answering a similar question, I discovered that you can avoid hard-coding the MAX_PATH by simply importing wintypes from the ctypes module: from ctypes import wintypes . Now rather than hard-coding the MAX_PATH as 260 , you can just access it like so: wintypes.MAX_PATH .

Источник

Читайте также:  Python pandas dataframe get row
Оцените статью