Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is Word installed and where? 1

Status
Not open for further replies.

Glasgow

IS-IT--Management
Jul 30, 2001
1,669
GB
I would like to detect within VB whether Word is installed and where the Word executable is on the disk. If possible I'd like to extend the capability to detect other applications in the same way. Can this be achieved somehow?

Any help would be appreciated.

Thank you.
 
you could try:

Private Sub find_word
Dim wordObj As Object
Dim sPath As String

On Error Resume Next
Set wordObj = GetObject(, "Word.Application")
If wordObj Is Nothing Then
MsgBox ("not running")
Set wordObj = createObject(, "Word.Application")
End If
sPath = wordObj.Path
MsgBox (sPath)

End Sub
 
whoops sorry ignore the comma in the line:

Set wordObj = createObject(, "Word.Application")

it should read

Set wordObj = createObject("Word.Application")

that'll teach me not to proof read after a cut'n'paste :->
 
This is another option. I modified it from a MS article to open up a url, but it can be used for any file. It basically creates a file with the extension and then uses that file as a test, it is then deleted.

'Modified from
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, ByVal lpParameters As String, _
ByVal lpDirectory As String, 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 Sub Command1_Click()
Dim FileName As String, Dummy As String
Dim BrowserExec As String * 255
Dim RetVal As Long
Dim FileNumber As Integer

' First, create a known, temporary HTML file
BrowserExec = Space(255)
FileName = "C:\temp\temphtm.doc"
FileNumber = FreeFile ' Get unused file number
Open FileName For Output As #FileNumber ' Create temp HTML file
Write #FileNumber, "test" ' Output text
Close #FileNumber ' Close file
' Then find the application associated with it
RetVal = FindExecutable(FileName, Dummy, BrowserExec)

BrowserExec = Trim(BrowserExec)
MsgBox BrowserExec

Kill FileName ' delete temp HTML file
End Sub
 
Thanks - that lot looks like it should send me in the right direction.
 
The first solution is very useful if you actually want an object to work with, and the second is ingenious if a little verbose. But if you want to find out about the executable location, you might want to use the registry. It's a little bit more complicated, but is very general and robust. I've used it to find the location of Adobe Acrobat Reader and Distiller, and MS Outlook for various applications. If this is what you think you want to do, post back and I'll post the code for you.

Regards
SmallCraig [upsidedown]
 
Thanks SmallCraig - I agree with your comments. I am using the 'ingenious' method for now and expect it could be used to find acrobat from a .pdf file in the same way but not really general purpose.

I would be interested in seeing the code - thank you.
 
Hi Glasgow,

As promised, here's the code I've used. This code is included in a module as a part of my project, and I add to it every time I need to find another program to run.

Code:
Option Explicit

' These APIs are used to run Acrobat/Reader from withing VB.
' Apparently, they get registry entries ...

Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
    (ByVal hKey As Long, ByVal lpSubKey As String, _
     ByVal dwReserved As Long, ByVal samDesired As Long, _
     phkResult As Long) As Long

Private Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, ByVal lpValueName As String, _
     ByVal lpdwReserved As Long, lpdwType As Long, lpData As Any, _
     lpcbData As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32" _
    (ByVal hKey As Long) As Long
    
Const HKEY_LOCAL_MACHINE As Long = &H80000002

Private Function fncGetRegString _
    (hInKey As Long, ByVal subkey As String, ByVal valname As String) As String

    Dim RetVal As String
    Dim hSubKey As Long
    Dim dwType As Long
    Dim SZ As Long
    
    Dim R As Long
    Dim v As String

    Const KEY_ALL_ACCESS As Long = &H3F
    Const ERROR_SUCCESS As Long = 0
    Const REG_SZ As Long = 1
    
    
    RetVal = ""
    
    R = RegOpenKeyEx(hInKey, subkey, 0, KEY_ALL_ACCESS, hSubKey)
    
    If R <> ERROR_SUCCESS Then
        GoTo Quit_Now
    End If
    
    SZ = 256
    v = String(SZ, 0)
    
    R = RegQueryValueEx(hSubKey, valname, 0, dwType, ByVal v, SZ)
    
    If R = ERROR_SUCCESS And dwType = REG_SZ Then
        SZ = SZ - 1
        RetVal = Left(v, SZ)
    Else
        RetVal = &quot;-- Not String --&quot;
    End If
    
    If hInKey = 0 Then
        R = RegCloseKey(hSubKey)
    End If
    
Quit_Now:
    fncGetRegString = RetVal
    
End Function

Public Function fncAcrobatViewer() As String
    Dim strViewer As String
    Dim intpos As Integer
    
    
    strViewer = fncGetRegString(HKEY_LOCAL_MACHINE, _
                    &quot;SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe&quot;, _
                    &quot;Path&quot;)

' Uses Acrobat if installed ...
    If strViewer <> &quot;&quot; Then
        strViewer = strViewer + &quot;\Acrobat.exe&quot;
    Else
' Acrobat is not installed
        strViewer = fncGetRegString(HKEY_LOCAL_MACHINE, _
                        &quot;SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe&quot;, _
                        &quot;Path&quot;)

' The function as included in the Acrobat Developer FAQ fails to account for the fact that
' the &quot;Path&quot; for &quot;AcroRd32.exe&quot; includes a SECOND path, separated from the first by a
' semi-colon, i.e., it is intended to be a DOS-style path.  The first part of the path is,
' fortunately, what we're after, so all we need to do is split off the bit before the
' semi-colon.  Since it seems virtually impossible to contact Adobe directly to tell them
' this, other programmers will have to suffer and find out for themselves.
        intpos = InStr(1, strViewer, &quot;;&quot;)
        
        If intpos = 0 Then
            strViewer = strViewer & &quot;\AcroRd32.exe&quot;
        Else
            strViewer = Left(strViewer, intpos - 1) & &quot;\AcroRd32.exe&quot;
        End If
    End If
    
    fncAcrobatViewer = strViewer

End Function

Public Function fncAcrobatDistiller() As String
    
    fncAcrobatDistiller = _
        fncGetRegString(HKEY_LOCAL_MACHINE, _
                        &quot;SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroDist.exe&quot;, _
                        &quot;Path&quot;) & _
        &quot;\AcroDist.exe&quot;

End Function

Public Function fncDistillerOptionsPath() As String
    Dim strAcrobatPath As String
    
    
    strAcrobatPath = fncAcrobatViewer

    fncDistillerOptionsPath = _
        Left(strAcrobatPath, InStrRev(strAcrobatPath, &quot;\&quot;)) & _
        &quot;\Distillr\Settings&quot;

End Function

Public Function fncOutlook() As String
    
    fncOutlook = fncGetRegString(HKEY_LOCAL_MACHINE, _
                    &quot;SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE&quot;, _
                    &quot;Path&quot;) & _
        &quot;\Outlook.exe&quot;

End Function

As you can see, the key to using this type of approach is knowing the registry designation of the program you're looking for. This can be quite easily found by running regedit and navigating down the tree to
HKEY_LOCAL_MACHINE
--> SOFTWARE
--> Microsoft
--> Windows
--> CurrentVersion
--> App Paths

and then finding the name of the program you want to locate. As you can see, I've developed new functions for each program I've wanted to find, but I'm sure with a bit of work you could make a much more general function to find any program you wanted. I'd be interested in your code if you did! By the way, I can't claim credit for the API calls, etc. - I got them from a VB code site. It would have been either VBSquare.com or VBExplorer.com, both of which I recommend if you ware looking for good code and tutorials. Another good site, especially for APIs, is AndreaVB.com.

To use the function, just set a string to it's value:

Code:
Dim strPath As String

strPath = fncOutlook

The catch is that you'll need another set of API calls to execute the program once you've located it. The code is as follows:

Code:
Option Explicit

' Structures declaration
Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type

' Function declaration
Private Declare Function WaitForSingleObject Lib &quot;kernel32.dll&quot; _
    (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    
Private Declare Function CloseHandle Lib &quot;kernel32.dll&quot; _
    (ByVal hObject As Long) As Long
    
Private Declare Function CreateProcessA Lib &quot;kernel32.dll&quot; _
    (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, _
     ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
     ByVal bInheritHandles As Long, _
     ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, _
     ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, _
     lpProcessInformation As PROCESS_INFORMATION) As Long

'Constants
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&
 
Public Function ExecuteTask(pPath As String, Optional pParameters As String = &quot;&quot;) As Long
    Dim proc As PROCESS_INFORMATION
    Dim startup As STARTUPINFO
    Dim lngRet As Long
    Dim strCmdLine As String


    strCmdLine = pPath
    If Trim(pParameters) <> &quot;&quot; Then
        strCmdLine = strCmdLine & &quot; &quot;&quot;&quot; & pParameters & &quot;&quot;&quot;&quot;
    End If
    
    ' Initialize the STARTUPINFO structure:
    startup.cb = Len(startup)
    
    ' Start the application:
    lngRet = CreateProcessA _
        (0&, strCmdLine, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, startup, proc)
        
    ExecuteTask = proc.hProcess
    
End Function

This code resides in a separate module to the first lot. Now, to run outlook using these two functions:

Code:
Dim lngTaskID As Long

lngTaskID = ExecuteTask(fncOutlook)

I did say it was a fair bit more complicated, but I'm sure you will find it worth the effort.

All the best with it,
SmallCraig[upsidedown]
 
Thanks for all that SmallCraig - I will now go forth and experiment.
 
smallcraig, how can you describe solution two as 'ingenious but verbose'? It's a pretty sound solution, and the verbosity part is merely a missed point error (the whole browser element is superfluous).

Your own solution is requires a function for each and every possible application, whereas solution two only requires a file extension.
 
Personally I still like my solution (I suppose I would), although it was a bit of a hatchet job from a specific solution (ie for IE). As strongm pointed out, my solution is flexible, indeed it can be modified so you just stick in an extention (eg xls) and it tells you where the exe is located.

We all have our own way of doing this I suppose

Grant
 
Grant, very neat. I need to find out whether word or excel exist, so I use your code but include a couple of little files with the setup. Then I just need a couple of lines of code. Thanks. Peter Meachem
peter @ accuflight.com

 
Just sticking my oar in - it is possible that the user will have Word installed but will have, say, MS WordView associated with the '.doc' extension. So, while I can certainly use Grant's solution (thanks again) it is not foolproof.

Despite the wording of my thread title, I am interested in something more general purpose. Not all executables will have a dedicated file extension either.

I'm grateful for everyone's input.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top