3

This used to work last week. I suspect a Windows update broke something. When using ShellExecute, it is forcing the URLs into lowercase, breaking parameter values passed to a case-sensitive server!

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

Sub OpenBrowser()
    Let RetVal = ShellExecute(0, "open", "http://yaHOO.com?UPPERCASE=lowercase")

Will open http://www.yahoo.com/?uppercase=lowercase

Version

I'm using Windows 8.1. I tried it in 3 browsers. Lowercase in Chrome, lowercase in IE, and Opera chops off the query parameter, but the host is lowercase.

Community
  • 1
  • 1
Chloe
  • 25,162
  • 40
  • 190
  • 357
  • This is what I get, the domain is lower-cased, but the params are correct http://imgur.com/FU5Mr3w Is this what you were previously getting? – David Zemens Nov 16 '13 at 20:50
  • No problem for me under Windows 7 pro. Some time browser may modify queries. – jacouh Nov 16 '13 at 20:58
  • @DavidZemens Yes that is what I was previously getting. Honestly I didn't try mixed case host, but really that is not important. The case of the parameters is very important. – Chloe Nov 16 '13 at 21:30

3 Answers3

3

Ok I solved it by creating a temporary HTML file, finding the executable associated with that, then launching the executable directly with the URL. Sheesh.

Private Const SW_SHOW = 5       ' Displays Window in its current size and position
Private Const SW_SHOWNORMAL = 1 ' Restores Window if Minimized or Maximized

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

Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" ( _
    ByVal lpFile As String, _
    ByVal lpDirectory As String, _
    ByVal lpResult As String _
    ) As Long

Private Declare Function GetTempPath Lib "kernel32" _
  Alias "GetTempPathA" ( _
    ByVal nBufferLength As Long, _
    ByVal lpBuffer As String) As Long

Private Declare Function GetTempFileName Lib "kernel32" _
  Alias "GetTempFileNameA" ( _
    ByVal lpszPath As String, _
    ByVal lpPrefixString As String, _
    ByVal wUnique As Long, _
    ByVal lpTempFileName As String) As Long

Public Function GetTempFileNameVBA( _
  Optional sPrefix As String = "VBA", _
  Optional sExtensao As String = "") As String
    Dim sTmpPath As String * 512
    Dim sTmpName As String * 576
    Dim nRet As Long
    Dim F As String
    nRet = GetTempPath(512, sTmpPath)
    If (nRet > 0 And nRet < 512) Then
      nRet = GetTempFileName(sTmpPath, sPrefix, 0, sTmpName)
      If nRet <> 0 Then F = Left$(sTmpName, InStr(sTmpName, vbNullChar) - 1)
      If sExtensao > "" Then
        Kill F
        If Right(F, 4) = ".tmp" Then F = Left(F, Len(F) - 4)
        F = F & sExtensao
      End If
      GetTempFileNameVBA = F
    End If
End Function

Sub Test_GetTempFileNameVBA()
    Debug.Print GetTempFileNameVBA("BR", ".html")
End Sub

Private Sub LaunchBrowser()
    Dim FileName As String, Dummy As String
    Dim BrowserExec As String * 255
    Dim RetVal As Long
    Dim FileNumber As Integer

    FileName = GetTempFileNameVBA("BR", ".html")
    FileNumber = FreeFile                    ' Get unused file number
    Open FileName For Output As #FileNumber  ' Create temp HTML file
        Write #FileNumber, "<HTML> <\HTML>"  ' Output text
    Close #FileNumber                        ' Close file
    ' Then find the application associated with it
    RetVal = FindExecutable(FileName, Dummy, BrowserExec)
    Kill FileName                   ' delete temp HTML file
    BrowserExec = Trim(BrowserExec)
    ' If an application is found, launch it!
    If RetVal <= 32 Or IsEmpty(BrowserExec) Then ' Error
        MsgBox "Could not find associated Browser", vbExclamation, "Browser Not Found"
    Else
        RetVal = ShellExecute(0, "open", BrowserExec, "http://www.yaHOO.com?case=MATTERS", Dummy, SW_SHOWNORMAL)
        If RetVal <= 32 Then        ' Error
            MsgBox "Web Page not Opened", vbExclamation, "URL Failed"
        End If
    End If
End Sub
Chloe
  • 25,162
  • 40
  • 190
  • 357
1

Use FileProtocolHandler instead of ShellExecute:

Public Declare Function FileProtocolHandler Lib "url.dll" _
      Alias "FileProtocolHandlerA" (ByVal hwnd As Long, ByVal hinst As Long, _
      ByVal lpszCmdLine As String, ByVal nShowCmd As Long) As Long

Public Sub OpenHyperlink(ByVal Url)
  FileProtocolHandler 0, 0, Url, 1
End Sub

With FileProtocolHandler, the lowercase conversion does not occur.

I have this problem under Windows 8.1, but not under Windows 7.

Christian d'Heureuse
  • 5,090
  • 1
  • 32
  • 28
-1

In my case using a temp ".html" file wasn't an option because those are linked to gedit so i can edit them.

I can't say if it works on the domain part, but i needed case sensitivity for the GET parameters.

I accomplished that by simple encoding everything in hex. Not just characters like "/" but everything.

user3437976
  • 101
  • 1
  • 6