dcsimg
Results 1 to 21 of 21

Thread: Short to Long File Names

  1. #1

    Thread Starter
    New Member
    Join Date
    Dec 2018
    Posts
    14

    Short to Long File Names

    So is there a limit to the number of dumb questions one can ask?

    I created a file association to launch a program and grab the file name from the command line. The only problem is that both the path and name are returned in a short format.

    Converting the short path to a long path was simple using the GetLongPathName API, but it only converts the path leaving a short file name.

    How does one go about converting a short file name to a long file name.

    Thanks.

  2. #2
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,338

    Re: Short to Long File Names

    I cannot test the function in Windows 10 because short path names are not supported any more, but: are you sure that the file that you are using to test is not actually named in short format? I mean that the file name is not literally something like "MyFile~3.ext"?

  3. #3
    Addicted Member
    Join Date
    Aug 2017
    Posts
    151

    Re: Short to Long File Names

    GetLongPathName seems to work as expected at least in Windows 7:

    Code:
    Private Declare Function GetLongPathNameW Lib "kernel32.dll" (ByVal lpszShortPath As Long, ByVal lpszLongPath As Long, ByVal cchBuffer As Long) As Long
    Private Declare Function GetShortPathNameW Lib "kernel32.dll" (ByVal lpszLongPath As Long, ByVal lpszShortPath As Long, ByVal cchBuffer As Long) As Long
    Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
    
    Public Function GetLongPathName(ByRef sPathName As String) As String
        Dim nSize As Long
    
        nSize = GetLongPathNameW(StrPtr(sPathName), 0&, 0&)
        If nSize = 0& Then Exit Function
        SysReAllocStringLen VarPtr(GetLongPathName), , nSize - 1&
        If GetLongPathNameW(StrPtr(sPathName), StrPtr(GetLongPathName), nSize) = 0& Then GetLongPathName = vbNullString
    End Function
    
    Public Function GetShortPathName(ByRef sPathName As String) As String
        Dim nSize As Long
    
        nSize = GetShortPathNameW(StrPtr(sPathName), 0&, 0&)
        If nSize = 0& Then Exit Function
        SysReAllocStringLen VarPtr(GetShortPathName), , nSize - 1&
        If GetShortPathNameW(StrPtr(sPathName), StrPtr(GetShortPathName), nSize) = 0& Then GetShortPathName = vbNullString
    End Function
    Code:
    ? """"; GetShortPathName("C:\Program Files (x86)\Microsoft Visual Studio\VB98\Template\Forms\Tip of the Day.frm"); """"
    "C:\PROGRA~2\MICROS~1\VB98\Template\Forms\TIPOFT~1.FRM"
    
    ? """"; GetLongPathName("C:\PROGRA~2\MICROS~1\VB98\Template\Forms\TIPOFT~1.FRM"); """"
    "C:\Program Files (x86)\Microsoft Visual Studio\VB98\Template\Forms\Tip of the Day.frm"
    MSDN mentions this in GetShortPathName's documentation:

    Quote Originally Posted by MSDN
    You can obtain the long name of a file from the short name by calling the GetLongPathName function. Alternatively, where GetLongPathName is not available, you can call FindFirstFile on each component of the path to get the corresponding long name.
    Code:
    Private Type WIN32_FIND_DATA
        dwFileAttributes   As Long
        ftCreationTime     As Currency
        ftLastAccessTime   As Currency
        ftLastWriteTime    As Currency
        nFileSize          As Currency
        dwReserved         As Currency
        cFileName          As String * 260
        cAlternateFileName As String * 14
    End Type
    
    Private Declare Function FindFirstFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal lpFindFileData As Long) As Long
    Private Declare Function FindClose Lib "kernel32.dll" (ByVal hFindFile As Long) As Long
    Private Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpString As Long) As Long
    
    Public Function GetLongFileName(ByRef sPathName As String) As String
        Const INVALID_HANDLE_VALUE = -1&
        Dim hFindFile As Long, WFD As WIN32_FIND_DATA
    
        hFindFile = FindFirstFileW(StrPtr(sPathName), VarPtr(WFD))
    
        If hFindFile <> INVALID_HANDLE_VALUE Then
            GetLongFileName = Left$(WFD.cFileName, lstrlenW(StrPtr(WFD.cFileName)))
            hFindFile = FindClose(hFindFile): Debug.Assert hFindFile
        End If
    End Function
    Code:
    ? """"; GetLongFileName("C:\PROGRA~2\MICROS~1\VB98\Template\Forms\TIPOFT~1.FRM"); """"
    "Tip of the Day.frm"
    Last edited by Victor Bravo VI; Jan 12th, 2019 at 04:53 AM. Reason: Optimized GetLongPathName & GetShortPathName a bit

  4. #4
    Junior Member
    Join Date
    Jan 2017
    Posts
    21

    Re: Short to Long File Names

    I try GetLongPathName/GetShortPathName in Win10 and it works fine, but only in the system drive, I have try
    Code:
    Dim ofs As New Scripting.FileSystemObject
    Dim f As String
    Dim of As File
    Debug.Print "SYSTEM DRIVE"
    f = "c:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    
    Debug.Print """"; GetShortPathName(f); """"
    Debug.Print """"; GetLongPathName(GetShortPathName(f)); """"
    Set of = ofs.GetFile(f)
    Debug.Print of.ShortName
    Debug.Print of.ShortPath
    Debug.Print """"; GetLongPathName(of.ShortPath); """"
    Debug.Print "NO SYSTEM DRIVE"
    f = "d:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    Debug.Print """"; GetShortPathName(f); """"
    Debug.Print """"; GetLongPathName(GetShortPathName(f)); """"
    Set of = ofs.GetFile(f)
    Debug.Print of.ShortName
    Debug.Print of.ShortPath
    Debug.Print """"; GetLongPathName(of.ShortPath); """"
    And the output was

    Code:
    SYSTEM DRIVE
    "c:\Basura\DIRECT~1\ARCHIV~1.TXT"
    "c:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    ARCHIV~1.TXT
    C:\Basura\DIRECT~1\ARCHIV~1.TXT
    "C:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    NO SYSTEM DRIVE
    "d:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    "d:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    archivo con nombre de prueba.txt
    D:\Basura\directorio prueba\archivo con nombre de prueba.txt
    "D:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    Seems that in Win10 there is not shortpaths in non system drives.
    When I try this in WinXP the output was
    Code:
    "c:\Basura\DIRECT~1\ARCHIV~1.TXT"
    "c:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    ARCHIV~1.TXT
    C:\Basura\DIRECT~1\ARCHIV~1.TXT
    "C:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    NO SYSTEM DRIVE
    "d:\Basura\DIRECT~1\ARCHIV~1.TXT"
    "d:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    ARCHIV~1.TXT
    D:\Basura\DIRECT~1\ARCHIV~1.TXT
    "D:\Basura\directorio prueba\archivo con nombre de prueba.txt"
    Last edited by gilman; Jan 12th, 2019 at 05:17 AM.

  5. #5
    Addicted Member
    Join Date
    Aug 2017
    Posts
    151

    Re: Short to Long File Names

    @gilman

    What's the file system of the non-system drive? Is it FAT32, NTFS, ReFS or something else? If it is NTFS, do you remember if you've turned off the creation of short file names? See How to disable 8.3 file name creation on NTFS partitions and NtfsDisable8dot3NameCreation to learn how to figure out if 8.3 filename creation is disabled.


    EDIT

    Is your Win XP installed on the same PC as your Win 10 (IOW, are both OS connected to the same drive(s))?
    Last edited by Victor Bravo VI; Jan 12th, 2019 at 06:35 AM.

  6. #6
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,338

    Re: Short to Long File Names

    Hello, in my Windows 10 (version 1709) when using GetShortPathName (using above code) with files on the system drive it seems to work "partially":

    Code:
    Debug.Print GetShortPathName("C:\Program Files (x86)\Microsoft Visual Studio\VB98\Long name file test.txt")
    I get:
    C:\PROGRA~2\Microsoft Visual Studio\VB98\Long name file test.txt

  7. #7
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    725

    Re: Short to Long File Names

    not sure why we need to convert short to long.
    usually we need the short, not long, since vb6 don't work well with long sometimes, depending on unicode and length.

    anyway, if this is a problem of the command line, you should use the API GetCommandLineW
    that way you get the "correct" command line parameter and if you need the short one, you use GetShortPathNameW

    another thing is the application path. not always it is possible to get it using app.path
    a workaround is to use GetModuleFileName

  8. #8
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,338

    Re: Short to Long File Names

    Quote Originally Posted by baka View Post
    not sure why we need to convert short to long.
    May be to show it to the user.

    Quote Originally Posted by baka View Post
    another thing is the application path. not always it is possible to get it using app.path
    What do you mean? (other than not having the last \ when it is on the root of the drive)

  9. #9
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    725

    Re: Short to Long File Names

    example: create a new project, and place
    Code:
    Private Sub Form_Load()
        Dim Data$
        Open App.Path & "\test.txt" For Input As #1
            Line Input #1, Data
        Close #1
        MsgBox Data
    End Sub
    compile the project into an executable, create a test.txt with something, like "hello" and save. try it.
    place this in C:\TEST\
    rename TEST to test˙ (where the last one is an ascii 255)
    run again.

  10. #10
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,338

    Re: Short to Long File Names

    Quote Originally Posted by baka View Post
    example: create a new project, and place
    Code:
    Private Sub Form_Load()
        Dim Data$
        Open App.Path & "\test.txt" For Input As #1
            Line Input #1, Data
        Close #1
        MsgBox Data
    End Sub
    compile the project into an executable, create a test.txt with something, like "hello" and save. try it.
    place this in C:\TEST\
    rename TEST to test˙ (where the last one is an ascii 255)
    run again.
    It works fine here.

  11. #11
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    12,666

    Re: Short to Long File Names

    I had almost forgotten abotu short file names. Been ages since I saw one on my systems.

  12. #12
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    725

    Re: Short to Long File Names

    im on windows 7, i get run-time error 76, path not found. try different combinations, maybe ascii255 is space for u. try ascii230 or something.
    no matter if it works for u, this is a problem. if u create a program u need to make it so as many possible can use it.

  13. #13
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,338

    Re: Short to Long File Names

    Quote Originally Posted by baka View Post
    im on windows 7, i get run-time error 76, path not found. try different combinations, maybe ascii255 is space for u. try ascii230 or something.
    no matter if it works for u, this is a problem. if u create a program u need to make it so as many possible can use it.
    I have Windows 10.
    If I type Alt+255 I get a non-breaking space. But in my test I copied "test˙" from your post and pasted it for the folder name into the explorer window.

    On other side, using:
    Code:
    Debug.Print AscW(Clipboard.GetText)
    If I copy the non-breaking space to the clipboard, I get 160 and if I copy ˙ I get 255.

    Strange. It seems that VB6 and Windows explorer don't use the same locale or something.

  14. #14

    Thread Starter
    New Member
    Join Date
    Dec 2018
    Posts
    14

    Re: Short to Long File Names

    When handed this project, I found the only copy of the code was on an old computer that I literally dusted & cleaned before using. It was also the only pc around with VB6 and its running XP.

    While this isn't a problem for newer OS's, it makes testing a bit of a problem and not sure with well over 1,000 pc's in the company there could be others outdated.

    The reason for wanting to convert to long names is that VB can't open the short files with the standard open call as it errors out.

    When using GetShortPathName, it returns nothing when I use a full file specification with short path + file name. To get it to return a long path I had to strip off the file name.

    Handing GetShortPathName just a short file name, returns nothing, an empty string.

    I went with trying the FindFirstFileW, but it returns with no files found when handing it short names.

    System
    Microsoft Windows XP
    Professional
    Version 2002
    Service Pack 3

    I'm about to try GetCommandLineW from one of the comments above and see if that works.

  15. #15
    Frenzied Member ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    1,545

    Re: Short to Long File Names

    can't you just rename the Files ?

    Code:
    rename verylo~1.txt newname.txt
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  16. #16

    Thread Starter
    New Member
    Join Date
    Dec 2018
    Posts
    14

    Re: Short to Long File Names

    I could rename it to a shorter file spec but I'm doing what I can to keep from being plagued with support calls if down the road users run into this same problem.

    From all I'm hearing you guys say, and all that I've looked into, this should be working.

    Besides not knowing what I'm doing, this is also the first time I've ever created a file association to launch a program by clicking on a file. Is it possible that I've done it incorrectly, or are there keys and or values to set / define in the registry controlling how command line arguments are handed off to programs?

    Like can one set things so short files names aren't allowed when a file association starts a program - I'm kind of grasping at straws now.

  17. #17
    Fanatic Member
    Join Date
    Dec 2014
    Posts
    725

    Re: Short to Long File Names

    GetCommandLineW is the one to use, vb6 can't handle unicode correctly and if the command line - path/file has extended ascii it could result in error, as the letter gets converted to something else.
    i have one old project where i take the command line, i use:
    Code:
    Private Function CommandU$()
        Dim pCL As Long
        Dim cCL As Long
        Dim ProgDelim As String
        Dim LPn$
        
        pCL = GetCommandLineW()
        cCL = lstrlenW(pCL)
        LPn$ = Space$(cCL)
        CommandU$ = Space$(256)
        lstrcpynW StrPtr(LPn$), pCL, cCL + 1
        If left$(LPn$, 1) = """" Then ProgDelim = """" Else ProgDelim = " "
        LPn$ = Trim$(Mid$(LPn$, InStr(2, LPn$, ProgDelim) + 1))
        If left$(LPn$, 1) = Chr(34) And right$(LPn$, 1) = Chr(34) Then LPn$ = Mid$(LPn$, 2, Len(LPn$) - 2)
        pCL = GetShortPathNameW(StrPtr(LPn$), StrPtr(CommandU$), 256)
        CommandU$ = left$(CommandU$, pCL)
    End Function
    and as u see im also converting it to shortpath before returning. if u only need the LongPath u skip that part.

  18. #18
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,013

    Re: Short to Long File Names

    Just as a related side-note, short (8.3) file names do sometimes come in handy. The command line "Dir /x" will give them to you. I recently had a file with some strange (possibly unicode) characters in the name, and the only way I could delete it was to go to a command prompt, find the short name, and then delete it with that short name.

    Also, as an FYI, you can disable the short (8.3) naming. However, I'd certainly recommend against it, precisely for the type of thing noted above.

    Take Care,
    Elroy
    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. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  19. #19
    Addicted Member
    Join Date
    Aug 2017
    Posts
    151

    Re: Short to Long File Names

    Quote Originally Posted by vblegacy View Post
    Besides not knowing what I'm doing, this is also the first time I've ever created a file association to launch a program by clicking on a file. Is it possible that I've done it incorrectly, or are there keys and or values to set / define in the registry controlling how command line arguments are handed off to programs?
    You may want to consult the Implementing a Custom File Format topic in the Shell Developer's Guide.

  20. #20

    Thread Starter
    New Member
    Join Date
    Dec 2018
    Posts
    14

    Re: Short to Long File Names

    .....
    Last edited by vblegacy; Jan 15th, 2019 at 11:19 AM.

  21. #21

    Thread Starter
    New Member
    Join Date
    Dec 2018
    Posts
    14

    Re: Short to Long File Names

    I'm starting to understand why some feel the need to toss a computer through a plate glass window.

    Even trying things I felt really shouldn't make a difference, but figured what the heck. Swapped out GetLongPathNameA with GetLongPathNameW, dumped VB Command for GetCommandLineW and read up on File Associations without any luck, and then threw in the towel...

    Took a new approach, something of a Hail Mary, Chkdsk, Virus Scan, Registry Cleaner, reloaded both Windows and VB service packs and hung a clove of garlic.

    I don't want to even get into the number of problems detected when cleaning up the system, I actually walked away several times while it spewed errors all over the screen.

    While it doesn't make a whole lot of sense to me, all of this has somehow fixed the problem. The short file name I was fighting is now working as it should.

    I feel bad and have to apologize for getting everyone involved here when it was just something stupid on my part for not having a 'clean' running system.

    I'll be sure to do a better job of checking things out before asking anymore questions.

    Code:
    Thanks everyone for all of the help. 
    
                     _\|/_
                     (o o)
            ------oOO-{_}-OOo------

Posting Permissions

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



Featured


Click Here to Expand Forum to Full Width