Besondere Ordner
Pfade zu vordefinierten Systemordnern auflösen
Windows hält ein Vielzahl vordefinierter Standardordner bereit, wie "Eigene Dateien", "Gemeinsame Dateien", Programme, Startmenü u.s.w., die auf jedem Rechner andere Pfade haben können. Passend dazu gibt es auch eine API Funktion, die die Pfade dieser Standardordner zur Laufzeit auflöst.
Wo findet man Ihr Windows - Verzeichnis? "C:\Windows" oder doch "C:\WinNT"? Wie wäre es mit "G:\WinNT"? Dies ist nur ein Beispiel für einen Systemordner, der auf jedem Rechner woanders zu finden sein kann. Windows hält eine Vielzahl weiterer Systemordner bereit, wie "Eigene Dateien", "Gemeinsame Dateien", Programme, Startmenü u.s.w.
Zum Ermitteln der Pfade dieser Systemordner stellt Windows die API Funktion SHGetSpecialFolderLocation bereit. Diese füllt eine ITEMIDLIST-Struktur mit den entsprechenden Informationen, der mit der Shell Funktion SHGetPathFromIDList der reine Pfad im Dateisystem entlockt werden kann.
Mit Windows 2000, aber auch schon zuvor durch den Internet Explorer, wurde der Pool der Systemordner noch einmal aufgestockt und über die Funktion SHGetSpecialFolderLocation können neben den neuen Ordnern "Anwendungsdaten", "Verwaltung" oder "Eigene Bilder", auch die Pfade des Windows bzw. System(32) Verzeichnisses ermittelt werden, wofür zuvor separate API Funktionen benötigt wurden. Zudem besteht über den Flag CSIDL_FLAG_CREATE, einen Ordner anzulegen, wenn er noch nicht existiert.
Für Windows 9x/ME/Windows NT wird diese erweiterte Funktionalität teilweise über die API Funktion SHGetFolderPath aus der weiterverteilbaren Datei "shfolder.dll" bereitgestellt. Welches System, welche Systemordner unterstützt und wo "SHGetFolderPath" aushilft, ist in folgender Tabelle zusammengefasst.
In der hier vorgestellten Funktion GetSpecialFolder, erfolgt der Aufruf der API Funktion SHGetFolderPath nur, wenn SHGetSpecialFolderLocation fehlgeschlagen ist und die Datei "shfolder.dll" vorhanden ist.
Private Type SHITEMID cb As Long abID As Byte End Type Private Type ITEMIDLIST mkid As SHITEMID End Type Private Declare Function SHGetFolderPath Lib "shfolder" Alias "SHGetFolderPathA" _ (ByVal hwndOwner As Long, ByVal nFolder As Long, _ ByVal hToken As Long, ByVal dwFlags As Long, _ ByVal pszPath As String) As Long Private Declare Function SHGetSpecialFolderLocation Lib "Shell32" _ (ByVal hwndOwner As Long, ByVal nFolder As Long, _ ByRef ppidl As ITEMIDLIST) As Long Private Declare Function SHGetPathFromIDList Lib "Shell32" _ (ByVal pidList As Long, ByVal lpBuffer As String) As Long Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" _ (ByVal lpLibFileName As String) As Long Private Declare Function FreeLibrary Lib "kernel32" _ (ByVal hLibModule As Long) As Long Private Const S_OK = 0 Private Const MAX_PATH = 260 Private Const CSIDL_FLAG_CREATE = &H8000& Public Enum ShellSpecialFolderConstants ssfDESKTOP = &H0 ssfPROGRAMS = &H2 ssfPERSONAL = &H5 ssfFAVORITES = &H6 ssfSTARTUP = &H7 ssfRECENT = &H8 ssfSENDTO = &H9 ssfSTARTMENU = &HB ssfDESKTOPDIRECTORY = &H10 ssfNETHOOD = &H13 ssfFONTS = &H14 ssfTEMPLATES = &H15 ssfCOMMONSTARTMENU = &H16 ssfCOMMONPROGRAMS = &H17 ssfCOMMONSTARTUP = &H18 ssfCOMMONDESKTOPDIRECTORY = &H19 ssfAPPDATA = &H1A ssfPRINTHOOD = &H1B ssfLOCALAPPDATA = &H1C ssfALTSTARTUP = &H1D ssfCOMMONALTSTARTUP = &H1E ssfCOMMONFAVORITES = &H1F ssfINTERNET_CACHE = &H20 ssfCOOKIES = &H21 ssfHISTORY = &H22 ssfCOMMONAPPDATA = &H23 ssfWINDOWS = &H24 ssfSYSTEM = &H25 ssfPROGRAMFILES = &H26 ssfMYPICTURES = &H27 ssfPROFILE = &H28 ssfPROGRAMFILESCOMMON = &H2B ssfCOMMONTEMPLATES = &H2D ssfCOMMONDOCUMENTS = &H2E ssfCOMMONADMINTOOLS = &H2F ssfADMINTOOLS = &H30 ssfCOMMONMUSIC = &H35 ssfCOMMONPICTURES = &H36 ssfCOMMONVIDEO = &H37 ssfRESOURCES = &H38 ssfRESOURCESLOCALIZED = &H39 ssfCDBURNAREA = &H3B End Enum Public Function GetSpecialFolder(ByVal Folder As ShellSpecialFolderConstants, _ Optional ByVal ForceCreate As Boolean) As String Dim tIIDL As ITEMIDLIST Dim strPath As String Dim hMod As Long If (ForceCreate) Then Folder = Folder Or CSIDL_FLAG_CREATE End If If SHGetSpecialFolderLocation(0, Folder, tIIDL) = S_OK Then strPath = Space$(MAX_PATH) If SHGetPathFromIDList(tIIDL.mkid.cb, strPath) <> 0 Then GetSpecialFolder = Left$(strPath, InStr(1, strPath, vbNullChar) - 1) End If Else strPath = Space$(MAX_PATH) hMod = LoadLibrary("shfolder") If (hMod <> 0) Then If SHGetFolderPath(0, Folder, 0, 0, strPath) = S_OK Then GetSpecialFolder = Left$(strPath, InStr(1, strPath, vbNullChar) - 1) End If FreeLibrary hMod End If End If End Function
- modGetSpecialFolder und Beispielprojekt (specialfolder.zip - 4 KB)
- Bezug des ShFolder DLL Redistributable über das Microsoft Download Center oder über die aktuelle Ausgabe des Platform SDK