Menu

[d09ac3]: / Module_FileSystem.bas  Maximize  Restore  History

Download this file

344 lines (271 with data), 11.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
Attribute VB_Name = "Module_FileSystem"
' ========================================================================
' == DanielsXLToolbox (c) 2008-2013 Daniel Kraus Licensed under GPLv2
' ========================================================================
' == DanielsXLToolbox.Module_FileSystem
' ==
' == Created: 02-Jul-09 19:14
' ==
' ==
' ==
' == 22-Jan-11 preliminarily 64bit safe
' == 05-Nov-11 GetText support
' ==
Option Explicit
Option Private Module
Public Const InvalidFileNameChars = "\/:*?""<>|" ' Characters that are not allowed in Windows file names
' *** Define Special Folder Constants
Private Const CSIDL_PROGRAMS = 2 ' Program Groups Folder
Private Const CSIDL_PERSONAL = 5 ' Personal Documents Folder
Private Const CSIDL_FAVORITES = 6 ' Favorites Folder
Private Const CSIDL_STARTUP = 7 ' Startup Group Folder
Private Const CSIDL_RECENT = 8 ' Recently Used Documents Folder
Private Const CSIDL_SENDTO = 9 ' Send To Folder
Private Const CSIDL_STARTMENU = 11 ' Start Menu Folder
Private Const CSIDL_DESKTOPDIRECTORY = 16 ' Desktop Folder
Private Const CSIDL_NETHOOD = 19 ' Network Neighborhood Folder
Private Const CSIDL_TEMPLATES = 21 ' Document Templates Folder
Private Const CSIDL_COMMON_STARTMENU = 22 ' Common Start Menu Folder
Private Const CSIDL_COMMON_PROGRAMS = 23 ' Common Program Groups
Private Const CSIDL_COMMON_STARTUP = 24 ' Common Startup Group Folder
Private Const CSIDL_COMMON_DESKTOPDIRECTORY = 25 ' Common Desktop Folder
Private Const CSIDL_APPDATA = 26 ' Application Data Folder
Private Const CSIDL_PRINTHOOD = 27 ' Printers Folder
Private Const CSIDL_COMMON_FAVORITES = 31 ' Common Favorites Folder
Private Const CSIDL_INTERNET_CACHE = 32 ' Temp. Internet Files Folder
Private Const CSIDL_COOKIES = 33 ' Cookies Folder
Private Const CSIDL_HISTORY = 34 ' History Folder
#If VBA7 Then
Private Declare PtrSafe Function SHGetFolderPath Lib "shell32" ( _
ByVal hwndOwner As LongPtr, _
ByVal nFolder As Integer, _
ByVal hToken As LongPtr, _
ByVal dwFlags As Long, _
ByRef pszPath As String) As Long
Public Declare PtrSafe Function SHGetSpecialFolderLocation _
Lib "shell32" (ByVal hwnd As LongPtr, _
ByVal nFolder As Long, ByRef ppidl As LongPtr) As Long
Public Declare PtrSafe Function SHGetPathFromIDList _
Lib "shell32" Alias "SHGetPathFromIDListW" _
(ByVal pidl As LongPtr, ByVal pszPath As LongPtr) As Long
Public Declare PtrSafe Sub CoTaskMemFree Lib "ole32" (ByVal pvoid As LongPtr)
#Else
Private Declare Function SHGetFolderPath Lib "shell32" ( _
ByVal hwndOwner As Long, _
ByVal nFolder As Integer, _
ByVal hToken As Long, _
ByVal dwFlags As Long, _
ByRef pszPath As String) As Long
Public Declare Function SHGetSpecialFolderLocation _
Lib "shell32" (ByVal hwnd As Long, _
ByVal nFolder As Long, ByRef ppidl As Long) As Long
Public Declare Function SHGetPathFromIDList _
Lib "shell32" Alias "SHGetPathFromIDListW" _
(ByVal pidl As Long, ByVal pszPath As Long) As Long
Public Declare Sub CoTaskMemFree Lib "ole32" (ByVal pvoid As Long)
#End If
Function GetFileNameOnly(ByRef aPath As String, Optional IncludePath As Boolean = False) As String
' Strips the file extension from aPath
Dim i As Long, PathSep As String
Dim s As String
PathSep = Application.PathSeparator
s = aPath
If InStr(aPath, ".") > 0 Then
i = Len(aPath)
Do While Mid$(aPath, i, 1) <> "."
i = i - 1
Loop
If i > 1 Then s = Left$(aPath, i - 1) Else s = "" ' If there is a period, but it's the first character in aPath, return nothing
End If
' Now, strip a potential path, if desired
If Not IncludePath Then
If InStr(s, PathSep) > 0 Then
i = Len(s)
Do While Mid$(s, i, 1) <> PathSep
i = i - 1
Loop
If i <> Len(s) Then s = Mid$(s, i + 1) Else s = "" ' If there is a path separator, but it's the last character in aPath, return nothing
End If
End If
GetFileNameOnly = s
End Function
Function GetFileExtOnly(ByRef aPath As String) As String
' This function will return the file extension in the path at hand including a leading dot
' If no file extension is found, an empty string is returned
Dim i As Long
If InStr(aPath, ".") > 0 Then
i = Len(aPath)
Do While Mid$(aPath, i, 1) <> "."
i = i - 1
Loop
GetFileExtOnly = Mid$(aPath, i)
Else ' No dot found, so no extension...
GetFileExtOnly = ""
End If
End Function
Function GetPath(ByRef aPath As String) As String
' Returns the path portion of the path/filename/extension string that is handed over.
' Will have a trailing "\". Will be EMPTY if no path separator is found.
Dim i As Long, PathSep As String
If Len(aPath) Then
PathSep = Application.PathSeparator
If InStr(aPath, PathSep) > 0 Then
i = Len(aPath)
Do While Mid$(aPath, i, 1) <> PathSep
i = i - 1
Loop
GetPath = Left$(aPath, i)
Else ' No path separator found, so no path...
GetPath = ""
End If
End If
End Function
Function StripPath(aPath As String) As String
' Strips the path information from a fully qualified file name.
' This function is not able to deal with file names in the form
' "c:filename.ext" as it searches for the path separator ("\").
Dim i As Long
Dim sPathSep As String
If Len(aPath) Then
sPathSep = Application.PathSeparator
If InStr(aPath, sPathSep) > 0 Then
i = Len(aPath)
Do While Mid$(aPath, i, 1) <> sPathSep
i = i - 1
Loop
StripPath = Mid$(aPath, i + 1)
Else ' No path separator found: return entire path
StripPath = aPath
End If
End If
End Function
Function CompletePath(aPath As String) As String
Dim PathSep As String
PathSep = Application.PathSeparator
If Right$(aPath, 1) = PathSep Then
CompletePath = aPath
Else
CompletePath = aPath & PathSep
End If
End Function
Function ValidFileNameString(ByRef fn As String) As Boolean
Dim i As Long
ValidFileNameString = True
For i = 1 To Len(fn)
If InStr(InvalidFileNameChars, Mid$(fn, i, 1)) <> 0 Then
ValidFileNameString = False
Exit Function
End If
Next i
End Function
Function MakeValidFileName(ByVal fn As String, Optional UseUnderscores As Boolean = False) As String
' Deletes each 'illegal' character in fn
' Changed declaration for version 2.71: "ByVal fn As String" instead of "ByRef fn As String"
' to avoid inadvertent messing around with the calling procedure's variable.
Dim i As Long
Dim c As String
If UseUnderscores Then c = "_" Else c = ""
i = 1
Do Until i > Len(fn)
If InStr(InvalidFileNameChars & Chr(13) & Chr(10), Mid$(fn, i, 1)) <> 0 Then
fn = Left$(fn, i - 1) & c & Mid$(fn, i + 1)
Else
i = i + 1
End If
Loop
MakeValidFileName = fn
End Function
Function CreatePath(ByRef aPath As String) As Boolean
' This function will try to generate the aPath
' in the file system. Unlike MkDir, it can create
' several subfolders at once.
' If successful, it returns TRUE.
' Note that the flag "vbHidden" has to be included
' in the Dir() calls so that hidden folders are
' recognized.
Dim i As Long
Dim SubPath As String
Dim PathSep As String
PathSep = Application.PathSeparator
aPath = AddPathSep(aPath)
i = InStr(aPath, PathSep)
Do
SubPath = Left$(aPath, i)
' Try to make the sub directory (it may exist already)
On Error Resume Next
MkDir SubPath
' Fix for version 2.71: error report 4KA3VR
' Do not crash ugly if creating the path failed;
' move the If(Len(Dir... statement inside the
' On Error Resume Next bracket.
' If the sub directory still does not exist,
' creating the path failed -- exit the function
If Len(dir(RemovePathSep(SubPath), vbDirectory Or vbHidden Or vbSystem)) = 0 Then GoTo ErrorExit
On Error GoTo 0
i = InStr(i + 1, aPath, PathSep)
Loop Until i = 0 ' Loop until no more path separators are found
CreatePath = Len(dir(RemovePathSep(aPath), vbDirectory Or vbHidden Or vbSystem)) <> 0
ErrorExit:
End Function
Function ChDirEx(path As String) As String
' Changes the working directory and drive; returns the old working directory
ChDirEx = CurDir
If path Like "?:*" Then ChDrive Left$(path, 2)
ChDir path
End Function
Private Function SpecFolder(ByVal lngFolder As Long) As String
' http://msdn.microsoft.com/en-us/library/aa140088(office.10).aspx
#If VBA7 Then
Dim ppidl As LongPtr
#Else
Dim ppidl As Long
#End If
Dim lngFolderFound As Long
Dim lngPidlFound As Long
Dim strPath As String
strPath = Space(MAX_PATH)
lngPidlFound = SHGetSpecialFolderLocation(0, lngFolder, ppidl)
If lngPidlFound = 0 Then
lngFolderFound = SHGetPathFromIDList(ppidl, StrPtr(strPath))
If lngFolderFound Then
SpecFolder = Left$(strPath, InStr(1, strPath, vbNullChar) - 1)
End If
End If
CoTaskMemFree ppidl
End Function
Function GetSpecialFolderDesktop() As String
GetSpecialFolderDesktop = SpecFolder(CSIDL_DESKTOPDIRECTORY)
End Function
Function GetSpecialFolderMyDocuments() As String
GetSpecialFolderMyDocuments = SpecFolder(CSIDL_PERSONAL)
End Function
Function FileExists(filename As String) As Boolean
On Error Resume Next
FileExists = Len(dir(filename, vbArchive Or vbDirectory Or vbHidden Or vbSystem)) <> 0
End Function
Function AddPathSep(s As String) As String
' This function adds a path separator to the
' path contained in s, unless there already
' is one.
Dim NewPath As String
Dim PathSep As String
PathSep = Application.PathSeparator
NewPath = Trim$(s)
If (Len(NewPath) > 0) And (Right$(NewPath, 1) <> PathSep) Then
NewPath = NewPath & PathSep
End If
AddPathSep = NewPath
End Function
Function RemovePathSep(s As String) As String
Dim NewPath As String
Dim PathSep As String
PathSep = Application.PathSeparator
NewPath = Trim$(s)
If (Right$(NewPath, 1) = PathSep) Then
NewPath = Left$(NewPath, Len(NewPath) - 1)
' Make sure not to remove the path separator
' after a drive symbol (root path)
If Right$(NewPath, 1) = ":" Then NewPath = NewPath & PathSep
End If
RemovePathSep = NewPath
End Function
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.