ms-accessunicodecharacter-encodingms-access-2013

in VBA (msaccess) , how to open a file with default program when I have unicode folder/file names


In MSAccess vba, I want to do something like import ShellExecute to open files with their default program.
But I must allow unicode characters in folder or file names (such as Chinese, Korean, Russian, Arabic).

There are good examples of ShellExecute
such as here: https://stackoverflow.com/a/20441268/1518460
or here: https://stackoverflow.com/a/32013971/1518460

And it's good to know to ignore the "?????" in strings in the UI in Access VBA. It makes it look like variables lost the Unicode values but actually the UI can't display Unicode. If the values came direct from the db, they should be fine. (see this).

But paths with Chinese or Korean still won't open, while paths with all ansi will.

I'm trying to use the same declare ShellExecute as in the first example above, taking paths from a linked table in my current Access app:

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, _
    ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, _
    ByVal lpDirectory As String, ByVal lpnShowCmd As Long) As Long



Private Sub btnLaunchFunVid1_Click()

    Dim strFileFolder As String
    Dim strFilename As String
    Dim strFullFilepath As String

    Dim rst As Recordset
    Dim qt As String
    qt = "select folderPath, filename from ClassAdmin_Videos where rowid = " & CStr(Me.cmbFunVideo1.Value)
    Set rst = CurrentDb.OpenRecordset(qt)

    strFileFolder = rst.Fields("folderPath")
    strFilename = rst.Fields("filename")

    strFullFilepath = strFileFolder & strFilename

    OpenFunVideoFileWithImportedShellExecute strFullFilepath


End Sub


Public Sub OpenFunVideoFileWithImportedShellExecute(ByVal Path As String)

    If Dir(Path) > "" Then
        ShellExecute 0, "open", Path, "", "", 0
    End If

End Sub

Is there an option I can set to allow Unicode?
Or is there a better function?


Solution

  • Yes, there is a better function.

    Note the function you're actually importing: "ShellExecuteA".

    Guess what the "A" stand for... it's the ansi version of the function.
    There is a "W" == wide == unicode version.

    A great basic example can be found here:
    http://www.vbforums.com/showthread.php?511136-how-to-use-shellexecute&p=4877907&viewfull=1#post4877907

    Using the same in your code would give:

    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteW" (ByVal hwnd As Long, ByVal lpOperation As Long, ByVal lpFile As Long, ByVal lpParameters As Long, ByVal lpDirectory As Long, ByVal nShowCmd As Long) As Long  
    
    '... 
    '    [no need to change the function getting the path] 
    '...
    
    Public Sub OpenFunVideoFileWithImportedShellExecute(ByVal Path As String)
    
        If Dir(Path) > "" Then
            ShellExecute 0, StrPtr("Open"), StrPtr(Path), 0, 0, 1
        End If
    
    End Sub