-
Nov 30th, 2022, 01:40 AM
#1
Thread Starter
Hyperactive Member
Error 5 : Bad filename or number, when trying to Dir$ a path
Hi friends,
Making backup and restore functions.
But I just fall on a bug.
In the export function, an ni file is also saved in the zip. In this file, are written locations of audio files included in the zip backup .
The import function unzip this ini file and unzip each files to their good place, following the directives of the ini file.
For example, an XP done under Win XP, where files are in "C:\Documents and settings". If I try to restore on a Win 10, as well as "Documents and settings" is replaced by "Users" and a junction is created for "Documents ans settings" , I'm on an Access denied on this directory.
I precise also that on one of my machines, "Users" folder is on D:\ .
I would test write access to a folder before writing inside (create subfolders and files, I already have a function to create recursive subfolders).
I tried GetAttr(path) (where path is "C:\Documents and settings\Couin\Desktop\Foo\Bar\Blabla.mp3" for example), but as well as the path dosen't exists, I get a File not found error.
Is there a way to test , something like CanIWrite(path) , with True/False or 1/0 answer ? (In case of 0 or False, I could change destination path).
Thanks
-
Nov 30th, 2022, 07:44 AM
#2
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Dir$ and other VB commands can't handle LongPath 100%, so either use that or convert LongPath to ShortPath
-
Nov 30th, 2022, 08:17 AM
#3
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
And you should use the SHGetSpecialFolderLocation API call to get your "special" folder locations, and not hard-code it.
Here's a wrapper for using it. Scroll down and see the GetSpecialFolder procedure.
Code:
Option Explicit
'
Public Enum CSIDL_CODE
CSIDL_DESKTOP = &H0& ' <desktop>
CSIDL_DESKTOPDIRECTORY = &H10& ' <user name>\Desktop
CSIDL_APPDATA = &H1A& ' <user name>\Application Data
CSIDL_LOCAL_APPDATA = &H1C& ' <user name>\Local Settings\Application Data (non roaming)
CSIDL_SYSTEM = &H25& ' GetSystemDirectory()
CSIDL_COMMON_DESKTOPDIRECTORY = &H19& ' All Users\Desktop
CSIDL_MYDOCUMENTS = 5&
CSIDL_MYPICTURES = &H27&
End Enum
#If False Then ' Intellisense fix.
Public CSIDL_DESKTOP, CSIDL_DESKTOPDIRECTORY, CSIDL_APPDATA, CSIDL_LOCAL_APPDATA, CSIDL_SYSTEM, CSIDL_COMMON_DESKTOPDIRECTORY, CSIDL_MYDOCUMENTS
#End If
'
' CSIDL_DESKTOP = &H0& ' <desktop>
' CSIDL_INTERNET = &H1& ' Internet Explorer (icon on desktop)
' CSIDL_PROGRAMS = &H2& ' Start Menu\Programs
' CSIDL_CONTROLS = &H3& ' My Computer\Control Panel
' CSIDL_PRINTERS = &H4& ' My Computer\Printers
' CSIDL_PERSONAL = &H5& ' My Documents
' CSIDL_FAVORITES = &H6& ' <user name>\Favorites
' CSIDL_STARTUP = &H7& ' Start Menu\Programs\Startup
' CSIDL_RECENT = &H8& ' <user name>\Recent
' CSIDL_SENDTO = &H9& ' <user name>\SendTo
' CSIDL_BITBUCKET = &HA& ' <desktop>\Recycle Bin
' CSIDL_STARTMENU = &HB& ' <user name>\Start Menu
' CSIDL_MYDOCUMENTS = &HC& ' logical "My Documents" desktop icon
' CSIDL_MYMUSIC = &HD& ' "My Music" folder
' CSIDL_MYVIDEO = &HE& ' "My Videos" folder
' CSIDL_DESKTOPDIRECTORY = &H10& ' <user name>\Desktop
' CSIDL_DRIVES = &H11& ' My Computer
' CSIDL_NETWORK = &H12& ' Network Neighborhood (My Network Places)
' CSIDL_NETHOOD = &H13& ' <user name>\nethood
' CSIDL_FONTS = &H14& ' windows\fonts
' CSIDL_TEMPLATES = &H15&
' CSIDL_COMMON_STARTMENU = &H16& ' All Users\Start Menu
' CSIDL_COMMON_PROGRAMS = &H17& ' All Users\Start Menu\Programs
' CSIDL_COMMON_STARTUP = &H18& ' All Users\Startup
' CSIDL_COMMON_DESKTOPDIRECTORY = &H19& ' All Users\Desktop
' CSIDL_APPDATA = &H1A& ' <user name>\Application Data
' CSIDL_PRINTHOOD = &H1B& ' <user name>\PrintHood
' CSIDL_LOCAL_APPDATA = &H1C& ' <user name>\Local Settings\Application Data (non roaming)
' CSIDL_ALTSTARTUP = &H1D& ' non localized startup
' CSIDL_COMMON_ALTSTARTUP = &H1E& ' non localized common startup
' CSIDL_COMMON_FAVORITES = &H1F&
' CSIDL_INTERNET_CACHE = &H20&
' CSIDL_COOKIES = &H21&
' CSIDL_HISTORY = &H22&
' CSIDL_COMMON_APPDATA = &H23& ' All Users\Application Data
' CSIDL_WINDOWS = &H24& ' GetWindowsDirectory()
' CSIDL_SYSTEM = &H25& ' GetSystemDirectory()
' CSIDL_PROGRAM_FILES = &H26& ' C:\Program Files
' CSIDL_MYPICTURES = &H27& ' C:\Program Files\My Pictures
' CSIDL_PROFILE = &H28& ' USERPROFILE
' CSIDL_SYSTEMX86 = &H29& ' x86 system directory on RISC
' CSIDL_PROGRAM_FILESX86 = &H2A& ' x86 C:\Program Files on RISC
' CSIDL_PROGRAM_FILES_COMMON = &H2B& ' C:\Program Files\Common
' CSIDL_PROGRAM_FILES_COMMONX86 = &H2C& ' x86 Program Files\Common on RISC
' CSIDL_COMMON_TEMPLATES = &H2D& ' All Users\Templates
' CSIDL_COMMON_DOCUMENTS = &H2E& ' All Users\Documents
' CSIDL_COMMON_ADMINTOOLS = &H2F& ' All Users\Start Menu\Programs\Administrative Tools
' CSIDL_ADMINTOOLS = &H30& ' <user name>\Start Menu\Programs\Administrative Tools
' CSIDL_CONNECTIONS = &H31& ' Network and Dial-up Connections
' CSIDL_COMMON_MUSIC = &H35& ' All Users\My Music
' CSIDL_COMMON_PICTURES = &H36& ' All Users\My Pictures
' CSIDL_COMMON_VIDEO = &H37& ' All Users\My Video
' CSIDL_RESOURCES = &H38& ' Resource Direcotry
' CSIDL_RESOURCES_LOCALIZED = &H39& ' Localized Resource Direcotry
' CSIDL_COMMON_OEM_LINKS = &H3A& ' Links to All Users OEM specific apps
' CSIDL_CDBURN_AREA = &H3B& ' USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
' CSIDL_COMPUTERSNEARME = &H3D& ' Computers Near Me (computered from Workgroup membership)
'
' CSIDL_FLAG_CREATE = &H8000& ' combine with CSIDL_ value to force folder creation in SHGetFolderPath()
' CSIDL_FLAG_DONT_VERIFY = &H4000& ' combine with CSIDL_ value to return an unverified folder path
' CSIDL_FLAG_NO_ALIAS = &H1000& ' combine with CSIDL_ value to insure non-alias versions of the pidl
' CSIDL_FLAG_PER_USER_INIT = &H800& ' combine with CSIDL_ value to indicate per-user init (eg. upgrade)
' CSIDL_FLAG_MASK = &HFF00& ' mask for all possible flag values
'
Private Declare Function SHGetSpecialFolderLocation Lib "shell32" (ByVal hWndOwner As Long, ByVal nFolder As Long, pIDL As Long) As Long
Private Declare Function SHGetPathFromIDListW Lib "shell32" (ByVal pIDL As Long, ByVal pszPath As Long) As Long
Private Declare Sub CoTaskMemFree Lib "ole32" (ByVal pv As Long)
Public Function GetSpecialFolder(ByVal CSIDL As CSIDL_CODE) As String
' Always includes terminating backslash.
Dim ppidl As Long
Const MAX_PATH As Long = 260&
'
If SHGetSpecialFolderLocation(0, CSIDL, ppidl) = 0 Then
GetSpecialFolder = String$(MAX_PATH, 0)
If SHGetPathFromIDListW(ppidl, StrPtr(GetSpecialFolder)) Then
GetSpecialFolder = RTrimNull(GetSpecialFolder)
AddSlash GetSpecialFolder
Else
GetSpecialFolder = vbNullString
End If
CoTaskMemFree ppidl
End If
End Function
Public Function RTrimNull(s As String) As String
RTrimNull = s
Do
If Right$(RTrimNull, 1&) <> vbNullChar Then Exit Do
RTrimNull = Left$(RTrimNull, Len(RTrimNull) - 1&)
Loop
End Function
Public Function AddSlash(sFldr As String) As String
' Only adds it if not there.
' This can be used as EITHER a sub or function, as it modifies the input.
If Right$(sFldr, 1) <> "\" Then sFldr = sFldr & "\"
AddSlash = sFldr
End Function
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Nov 30th, 2022, 09:31 AM
#4
Thread Starter
Hyperactive Member
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Hi friends,
Thanks for answers.
About Longpath to Short path, I got some result, based on https://www.vbforums.com/showthread....l=1#post255404
But about GetSpecialFolder, I don't find at all what to do with it for what I want to do ?
Or perhaps my request is not really clear ?
-
Nov 30th, 2022, 10:42 AM
#5
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
this one I use in my programs to get the current folder where the EXE is
Code:
Private Declare Function GetShortPathName Lib "kernel32.dll" Alias "GetShortPathNameW" (ByVal lpszLongPath As Long, ByVal lpszShortPath As Long, ByVal cchBuffer As Long) As Long
Private Declare Function GetCurrentDirectoryW Lib "kernel32" (ByVal nBufferLength As Long, ByVal lpBuffer As Long) As Long
Code:
Dim CurrentDirectory$
Dim LongDirectory$
CurrentDirectory = Space$(999)
LongDirectory = CurrentDirectory
GetCurrentDirectoryW 999, StrPtr(LongDirectory)
CurrentDirectory = Left$(CurrentDirectory, GetShortPathName(StrPtr(LongDirectory), StrPtr(CurrentDirectory), 999)) & "\"
this because app.path is not reliable.
once I get the shortpath, I don't need any convertion anymore,
this because everything inside my project will be using "valid" names.
the reason I need to know the folder is because if a user is download my project and he places it somewhere with letters or longpath not compatible with VB6 i/o
it will not work.
-
Nov 30th, 2022, 11:18 AM
#6
Thread Starter
Hyperactive Member
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Hi Baka,
thanks for your answer, but, I understand nothing
I think there is a language barrier because I don't want to know what is the path where exe is running, I want make the app testing if can access (with write availability) to a given path, designed from a ini file (like a table of contents).
-
Nov 30th, 2022, 11:50 AM
#7
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Here are some links on how to check whether write access is available for a folder:
https://www.vbforums.com/showthread....er-permissions
https://stackoverflow.com/questions/...ss-to-a-folder
https://social.msdn.microsoft.com/Fo...forum=exceldev
However, once you have determined that you do not have write access to the replacement for the XP folders that you would have had write access to, what are you planning to do then?
The point is that you should be placing the user files in the appropriate folder for the version of Windows that the program is running on, and that was what Elroy's code would help you do.
-
Nov 30th, 2022, 12:50 PM
#8
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
the problem here is not just restricted folders, but he uses Dir$
I mean, if the folder is locked, he would not be able to enter it
but if he can find the file from fileexplorer, it means its not locked but he's doing something wrong in VB6.
Code:
Private Function IsPathAvailable(ByVal sPath As String) As Boolean
Dim ShortPath$
ShortPath = Space$(260)
If GetShortPathName(StrPtr(sPath), StrPtr(ShortPath), 260) = 0 Then
Exit Function
Else
If GetAttr(ShortPath) And vbSystem Then Exit Function
End If
IsPathAvailable= True
End Function
I posted an example just to show how to use short/longpath. but u didnt understand.
-
Dec 1st, 2022, 08:09 AM
#9
Thread Starter
Hyperactive Member
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Hi friends
@jdc2000 : Thanks, I'll try to find what I need in your links
Also, I understand now the Elroy's answers, about replacing destination path. In fact, I plan to put files in a subfolder of App path, when target is not reachable/writable.
@baka : About short path, like I was writing in my message (#4), it was Ok, I found a code example and when I try with "C:\Documents and Settings", I get "C:\DOCUME~1"
Originally Posted by baka
I mean, if the folder is locked, he would not be able to enter it
but if he can find the file from fileexplorer, it means its not locked but he's doing something wrong in VB6.
The folder (in fact, in the example here, it is a Windows 10 junction) is not browsable from Explorer (Access denied).
-
Dec 1st, 2022, 10:02 AM
#10
Thread Starter
Hyperactive Member
Re: Error 5 : Bad filename or number, when trying to Dir$ a path
Originally Posted by Elroy
And you should use the SHGetSpecialFolderLocation API call to get your "special" folder locations, and not hard-code it.
Here's a wrapper for using it. Scroll down and see the GetSpecialFolder procedure.
Hi Elroy,
I come back to you about using GetSpecialFolder.
As well as I perhaps will try to change my "export" script, I can be brought to use it, to "standardize" between Windows version and Export/Import.
For example, if a file to export (in a Zip file), is located on XP in :
C:\Documents and Settings\Couin\Bureau\Blablabla.mp3
Instead of zipping it in :
C/Documents and Settings/Couin/Bureau/Blablabla.mp3
I would export in zip, as :
CSIDL_DESKTOPDIRECTORY/Blablabla.mp3
or better :
H0/Blablabla.mp3
Ok I understand that I can get the desktop path with
Code:
MsgBox GetSpecialFolder(CSIDL_DESKTOP)
But I don't understand how to use enum ? How can I find the which enum item is matching to the path of file ?
Is there a way to test for each enum?
Something like
Code:
Public function GetCSIDLCodeFromPath(Byval filepath As string) As string
For I = 0 To Ubound(CSIDL_CODE)
If InStr(1, filepath, CSIDL_CODE(I).Item) > 0 Then
GetCSIDLCodeFromPath = CSIDL_CODE(I).Value
Exit for
Next I
End Function
Of course, this function does not run, it's to show the idea of looping through enum. Searching infos about enum looping since 2 hours but find nothing. I don't understand the goal of enum
An idea ?
thanks
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|