From: Nobody on
It seems that FindExecutable() is unreliable for extensions with more than 3
letters. Here is a version based on AssocQueryString(), this function
doesn't require an existing file:

Option Explicit

Private Const MAX_PATH = 260

' AssocQueryString
Enum ASSOCF
ASSOCF_INIT_NOREMAPCLSID = &H1
ASSOCF_INIT_BYEXENAME = &H2
ASSOCF_OPEN_BYEXENAME = &H2
ASSOCF_INIT_DEFAULTTOSTAR = &H4
ASSOCF_INIT_DEFAULTTOFOLDER = &H8
ASSOCF_NOUSERSETTINGS = &H10
ASSOCF_NOTRUNCATE = &H20
ASSOCF_VERIFY = &H40
ASSOCF_REMAPRUNDLL = &H80
ASSOCF_NOFIXUPS = &H100
ASSOCF_IGNOREBASECLASS = &H200
End Enum
Enum ASSOCSTR
ASSOCSTR_COMMAND = 1
ASSOCSTR_EXECUTABLE
ASSOCSTR_FRIENDLYDOCNAME
ASSOCSTR_FRIENDLYAPPNAME
ASSOCSTR_NOOPEN
ASSOCSTR_SHELLNEWVALUE
ASSOCSTR_DDECOMMAND
ASSOCSTR_DDEIFEXEC
ASSOCSTR_DDEAPPLICATION
ASSOCSTR_DDETOPIC
ASSOCSTR_INFOTIP
ASSOCSTR_QUICKTIP
ASSOCSTR_TILEINFO
ASSOCSTR_CONTENTTYPE
ASSOCSTR_DEFAULTICON
ASSOCSTR_SHELLEXTENSION
ASSOCSTR_MAX
End Enum
Private Declare Function AssocQueryString Lib "shlwapi.dll" Alias _
"AssocQueryStringA" (ByVal flags As ASSOCF, ByVal str As ASSOCSTR, _
ByVal pszAssoc As String, ByVal pszExtra As String, _
ByVal pszOut As String, ByRef pcchOut As Long) As Long

Private Sub Form_Load()
Debug.Print "GetAssociatedEXE: '" & GetAssociatedEXE(".accdb") & "'"
End Sub

Private Function GetAssociatedEXE(sExtension As String) As String
Dim ret As Long
Dim sResult As String
Dim pcchOut As Long

sResult = String(MAX_PATH, 0)
pcchOut = Len(sResult)

ret = AssocQueryString(0, ASSOCSTR_EXECUTABLE, sExtension, "open", _
sResult, pcchOut)
Debug.Print "AssocQueryString returned " & ret & ", LastDllError: " & _
Err.LastDllError
If ret = 0 Then
' AssocQueryString succeeded
sResult = TrimNull(sResult)
GetAssociatedEXE = sResult
End If
End Function

Private Function TrimNull(s As String) As String
Dim pos As Long

pos = InStr(s, Chr(0))

If pos <> 0 Then
TrimNull = Trim(Left(s, pos - 1))
Else
TrimNull = Trim(s)
End If

End Function




From: Mike Williams on
"Nobody" <nobody(a)nobody.com> wrote in message
news:OMU2RuKNKHA.508(a)TK2MSFTNGP06.phx.gbl...

> It seems that FindExecutable() is unreliable for extensions with more than
> 3 letters. Here is a version based on
> AssocQueryString(), this function doesn't require an
> existing file:

Thanks. That works fine. I did actually notice the reference to
AssocQueryString when I was checking the details for FindExecutable on:

http://msdn.microsoft.com/en-us/library/bb776419(VS.85).aspx

According to that page you should use FindExecutable if you want to retrieve
the executable associated with a document file and AssocQueryString if you
want to find the path of an executable. Since FindExecutable (when it
works!) actually does return the path and filename of the executable
associated with a document then I assumed AssocQueryString was designed to
be used to return the full path of a registered executable when you passed
it only the name of the executable, and so I never gave it a try. Thanks for
the clarification and the code.

I really do wish that Micro$oft would learn to write help files in such a
way that they do actually help people!

Mike



From: Karl E. Peterson on
Nobody wrote:
> It seems that FindExecutable() is unreliable for extensions with more than 3
> letters. Here is a version based on AssocQueryString(),

Have you found it unreliable in any manner other than not returning an answer? (I'm
assuming it's not returning a *wrong* answer, is it?) I'm thinking, maybe call the
routine with FindExecutable first, then fall back to AssocQueryString if that first
one doesn't work. Reason being, AssocQueryString requires IE5 on older systems
(NT4/9x) and you resported (in another post) that FindExecutable seems to work okay
at 98?
--
..NET: It's About Trust!
http://vfred.mvps.org


From: Nobody on
"Karl E. Peterson" <karl(a)exmvps.org> wrote in message
news:%23J71P$wNKHA.352(a)TK2MSFTNGP02.phx.gbl...
> Nobody wrote:
>> It seems that FindExecutable() is unreliable for extensions with more
>> than 3
>> letters. Here is a version based on AssocQueryString(),
>
> Have you found it unreliable in any manner other than not returning an
> answer? (I'm assuming it's not returning a *wrong* answer, is it?) I'm
> thinking, maybe call the routine with FindExecutable first, then fall back
> to AssocQueryString if that first one doesn't work. Reason being,
> AssocQueryString requires IE5 on older systems (NT4/9x) and you resported
> (in another post) that FindExecutable seems to work okay at 98?

I don't know if AssocQueryString is always reliable, I don't use it often,
but FindExecutable works with 4 letters extensions(ACCDB) on Windows 98, but
not on XP.