Results 1 to 10 of 10

Thread: Error 5 : Bad filename or number, when trying to Dir$ a path

  1. #1

    Thread Starter
    Hyperactive Member Couin's Avatar
    Join Date
    Dec 2020
    Posts
    272

    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
    1 Hour vinyl mix live on Eurodance90 each sunday 10:00 PM (French Timezone) - New non-official Jingle Palette update Jingle Palette Reloaded

  2. #2
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    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

  3. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    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.

  4. #4

    Thread Starter
    Hyperactive Member Couin's Avatar
    Join Date
    Dec 2020
    Posts
    272

    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 ?
    1 Hour vinyl mix live on Eurodance90 each sunday 10:00 PM (French Timezone) - New non-official Jingle Palette update Jingle Palette Reloaded

  5. #5
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    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.

  6. #6

    Thread Starter
    Hyperactive Member Couin's Avatar
    Join Date
    Dec 2020
    Posts
    272

    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).

    1 Hour vinyl mix live on Eurodance90 each sunday 10:00 PM (French Timezone) - New non-official Jingle Palette update Jingle Palette Reloaded

  7. #7
    PowerPoster jdc2000's Avatar
    Join Date
    Oct 2001
    Location
    Idaho Falls, Idaho USA
    Posts
    2,393

    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.

  8. #8
    The Idiot
    Join Date
    Dec 2014
    Posts
    2,721

    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.

  9. #9

    Thread Starter
    Hyperactive Member Couin's Avatar
    Join Date
    Dec 2020
    Posts
    272

    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"

    Quote Originally Posted by baka View Post
    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).
    1 Hour vinyl mix live on Eurodance90 each sunday 10:00 PM (French Timezone) - New non-official Jingle Palette update Jingle Palette Reloaded

  10. #10

    Thread Starter
    Hyperactive Member Couin's Avatar
    Join Date
    Dec 2020
    Posts
    272

    Re: Error 5 : Bad filename or number, when trying to Dir$ a path

    Quote Originally Posted by Elroy View Post
    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
    1 Hour vinyl mix live on Eurodance90 each sunday 10:00 PM (French Timezone) - New non-official Jingle Palette update Jingle Palette Reloaded

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width