2015-04-27 49 views
1

在python中確定Windows 的路徑的最佳方法是什麼?python中的Windows特殊文件夾和已知文件夾(開始菜單,下載...)

我發現了一些特殊文件夾的常用方法,也就是CSIDL,但是對於KNOWNFOLDERID沒有任何直接的方法。向後兼容性得到維護,因此CSIDL方法仍然可以工作,但是自Windows XP以來所引入的任何特殊/已知文件夾未在此列舉。 「新」不可用的例子包括下載,播放列表,程序文件x64。

特殊文件夾

  • Find system folder locations in Python - 最簡單的CSIDL方法,依賴於win32com,適合AllUsersDesktop,AllUsersStartMenu,AllUsersPrograms,AllUsersStartup,桌面,收藏夾,字體,我的文檔,NETHOOD,PRINTHOOD,最近,SendTo,StartMenu,啓動&模板(列表可能不完整)。

  • How to get path of Start Menu's Programs directory? - 具有相同的方法如上述,以及使用ctypes的方法直接,所以win32com不需要(不作爲清楚或簡單)

已知文件夾

無論是在一個

+0

維基百科在** http://en.wikipedia.org/wiki/Special_folder#List_of_special_folders** – Marichyasana

+0

上有一個列表。謝謝@Marichyasana,但我需要確定它們在運行時是什麼動態的。它們並不總是具有相同的拼寫(不同的語言),並且可以根據組策略和/或其他自定義設置在不同的位置。該維基百科列表也非常不完整。 –

回答

2

你解決這個問題的方式作爲一個相同的:首先,你發現在C++,C#或VB文檔和理想一些不錯的示例代碼,然後你找出如何使用PyWin32做出同樣的外殼API或者IKnownFolder來自Python的COM調用。

由於上Known Folders的MSDN文檔概述說,你可以使用新的外殼包裝函數SHGetKnownFolderPath而不是舊的SHFolderPathSHGetFolderPath的,或者您也可以通過COM使用完整IKnownFolderManager接口。

不幸的是,我沒有一臺Windows機器在我面前,MSDN的示例下載沒有響應,所以我將不得不做一些猜測。但它可能是這樣的:

from win32com.shell import shell, shellcon 
path = shell.SHGetKnownFolderPath(shellcon.FOLDERID_AccountPictures, 
            0, # see KNOWN_FOLDER_FLAG 
            0) # current user 

如果shellcon沒有FOLDERID值,你必須看看他們在KNOWNFOLDERID和定義,你需要自己的常量。

如果shell沒有SHGetKnownFolderPath功能,你必須實例化一個IKnownFolderManager並調用GetFolderByName

如果shell甚至沒有IKnownFolderManager ...但Google的快速顯示it was added in build 218,所以這不會是一個問題。


如果您寧願通過​​做得比win32com,將(再次,未經測試,因爲我沒有Windows中和MSDN的服務器壞了)是這個樣子:

from ctypes import windll, wintypes 
from ctypes import * 
from uuid import UUID 

# ctypes GUID copied from MSDN sample code 
class GUID(Structure): 
    _fields_ = [ 
     ("Data1", wintypes.DWORD), 
     ("Data2", wintypes.WORD), 
     ("Data3", wintypes.WORD), 
     ("Data4", wintypes.BYTE * 8) 
    ] 

    def __init__(self, uuidstr): 
     uuid = UUID(uuidstr) 
     Structure.__init__(self) 
     self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid.fields 
     for i in range(2, 8): 
      self.Data4[i] = rest>>(8-i-1)*8 & 0xff 

FOLDERID_AccountPictures = '{008ca0b1-55b4-4c56-b8a8-4de4b299d3be}' 

SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath 
SHGetKnownFolderPath.argtypes = [ 
    POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, POINTER(c_char_p)] 

def get_known_folder_path(uuidstr): 
    pathptr = c_wchar_p() 
    guid = GUID(uuidstr) 
    if SHGetKnownFolderPath(byref(guid), 0, 0, byref(pathptr)): 
     raise Exception('Whatever you want here...') 
    return pathptr.value 
+0

你的直覺是正確的,win32com.shell沒有SHGetKnownFolderPath函數,至少在我的Win7 py27機器上沒有。通過COM實例化IKnownFolderManager超出了我目前的理解範圍。我最終跟蹤了你的線索到'shell.IID_IKnownFolderManagement'(謝謝,我沒有使用舊的pywin32),但GetFolderByName屬性不存在。 「網絡搜索沒有返回示例,只是宣佈它可用。我發現像'shell.FOLDERID_Downloads'這樣的項目返回一個IID代碼,但我一直無法弄清楚如何使用它來獲得路徑。 –

+0

我承認困惑。 Windows KnownFolders已經出現了很長一段時間,我預計會指向一條走完的道路。我想我已經被寵壞了,因爲我迄今爲止的大部分蟒蛇任務都是電池包括的。 :) ...我會明天探索ctypes的例子。也許這會給我帶來更多的成果。 (幾乎忘記了:非常感謝你給我一些東西讓毛孔粗大和咀嚼。) –

+0

記得我昨天偶然發現了這個ctypes的例子,https://gist.github.com/mkropat/7550097。它與你的相似,儘管我還沒有仔細研究它,看看相似只是表面的。在我的快速初始測試中,它總是返回默認值而不是當前用戶。 –

相關問題