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