Is there any way I can programatically query the current Windows environment, and get back a list of all the programs that are running? I need to retrieve something like the Applications tab you see in Windows Task Manager, because I need to know what if any websites are open.
Subject: list of all apps running on the computer
Is this what You are looking for?
I compiled a ScriptLib. Just create a new scriplib and import the following:
'CLASSProcessesEnum:
Option Public
Option Explicit
Const INVALID_HANDLE_VALUE = -1
Const TH32CS_SNAPPROCESS = 2
Public Type PROCESSENTRY32
size As Long
usage As Long
processId As Long
defaultHeapId As Long
moduleId As Long
cntThreads As Long
parentProcessId As Long
classBase As Long
flags As Long
exeFile As String * 500
End Type
Declare Function kCloseHandle Lib “kernel32.dll” Alias “CloseHandle” (Byval hObject As Long) As Long
Declare Function kCreateToolhelpSnapshot Lib “kernel32.dll” Alias “CreateToolhelp32Snapshot” (Byval flags As Long, Byval processId As Long) As Long
Declare Function kProcessFirst Lib “kernel32.dll” Alias “Process32First” (Byval hSnapshot As Long, processEntry As PROCESSENTRY32) As Long
Declare Function kProcessNext Lib “kernel32.dll” Alias “Process32Next” (Byval hSnapshot As Long, processEntry As PROCESSENTRY32) As Long
Dim retVal As Long
Dim hSnapshot As Long
Dim processEntry As PROCESSENTRY32
Dim oldCapacity As Long
Dim newCapacity As Long
Public Class ProcessesEnum
Private mProcessEntries() As String
Private mbIsOK As Boolean
Public Property Get ProcessEntry(lngIndex As Long) As String
If lngIndex > Ubound(mProcessEntries) Or lngIndex < 0 Then
Error 1001, "Index out of bounds"
Else
ProcessEntry = mPRocessEntries(lngIndex)
End If
End Property
Public Property Get ProcessCount As Long
ProcessCount = Ubound(mProcessEntries)
End Property
Public Sub New()
If getProcessNames(mProcessEntries()) Then
mbIsOK = True
Else
mbIsOK = False
Error 1002, "Unable to load processes."
End If
End Sub
End Class
Private Function getProcessNames(processes() As String) As Long
Dim lngCount As Long
lngCount = 0
hSnapshot = kCreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0)
If hSnapshot = INVALID_HANDLE_VALUE Then
retVal = 0
Else
processEntry.size = Len(processEntry)
If kProcessFirst(hSnapshot, processEntry) Then
Redim processes(0 To 0)
Do
Call ensureCapacityString(processes, retVal,0)
processes(lngCount) = getNullTerminatedString(processEntry.exeFile)
lngCount = lngCount + 1
Loop While kProcessNext(hSnapshot, processEntry)
If retVal <= Ubound(processes) Then
Redim Preserve processes(0 To lngCount - 1)
End If
retVal = 1
Else
retVal = 0
End If
Call kCloseHandle(hSnapshot)
End If
getProcessNames = retVal
End Function
Private Sub ensureCapacityString(vector() As String, size As Long, chunk As Long)
If chunk = 0 Then
chunk = 256
End If
oldCapacity = 1 - Lbound(vector) + Ubound(vector)
'newCapacity = IIf(size And 255 = 0, size, 256 * (1 + size \ 256))
If (size And 255 = 0) Then
newCapacity = size
Else
newCapacity = 256 * (1+size \ 256)
End If
If oldCapacity < newCapacity Then
Redim Preserve vector(Lbound(vector) To Lbound(vector) - 1 + newCapacity)
End If
End Sub
Private Function getNullTerminatedString(strValue As String) As String
Dim i As Long
i = Instr(strValue, Chr$(0))
If i = 0 Then
getNullTerminatedString = Left$(strValue, Len(strValue))
Else
getNullTerminatedString = Left$(strValue, i - 1)
End If
End Function
Then You can get all the processes by:
Dim pe As New ProcessesEnum
Dim strTemp As String
For lngCount = 0 To pe.ProcessCount
strTemp = strTemp & pe.ProcessEntry(lngCount) & Chr$(13)
Next
'Msgbox strTemp, 64, "All Processes:"
hth
Subject: RE: list of all apps running on the computer
Thanks.
This isn’t exactly what I wanted, because it gives back a list of the underlying processes (IOW the “processes” tab of Task Manager), not the actual programs (IOW the “applications” tab). However, it’s a very clever piece of code. If you can think of a way to adapt it to get back the other information, it would be exactly what I need.
One comment - you need to explicitly declare lngCount=Long in the code that invokes the library, otherwise it doesn’t compile.
Subject: RE: list of all apps running on the computer
Ok - I’ll see what I can come up with. Keep Your eyes open…
Thanks for the comment - I must have forgotten to declare the variable. I’ll change the code.
Subject: RE: list of all apps running on the computer
I found another approach:
The Word application does hold a tasks-object that holds all running applications. Try this:
Dim objWord As Variant
Dim objTasks As Variant
Dim lngCount As Long
Dim strTemp As String
Set objWord = CreateObject("Word.Application")
Set objTasks = objWord.Tasks
For lngCount = 1 To objTasks.Count
If objTasks(lngCount).Visible = True Then
strTemp = strTemp & objTasks(lngCount).Name & Chr$(13)
End If
Next 'lngCount
Msgbox strTemp,64,"ALL"
Subject: terrific !!! (but one more question)
That’s it - exactly what I need - as long as the computer has Word installed. Here’s a link to a page that tells more about it…
http://www.microsoft.com/technet/scriptcenter/topics/office/tasks.mspx
My next question is - what if they are running something else (especially Lotus Symphony) instead of Office.
Subject: RE: terrific !!! (but one more question)
After quite some intense searching and testing I found this piece of code:
Declare Function GetDesktopWindow Lib “user32” () As Long
Declare Function GetWindow Lib “user32” (Byval hwnd As Long, Byval wCmd As Long) As Long
Declare Function GetParent Lib “user32” (Byval hwnd As Long) As Long
Declare Function GetWindowText Lib “user32” Alias “GetWindowTextA” (Byval hwnd As Long, Byval lpString As String, Byval cch As Long) As Long
Declare Function GetWindowTextLength Lib “user32” Alias “GetWindowTextLengthA” (Byval hwnd As Long) As Long
Declare Function IsWindowVisible Lib “user32” (Byval hWnd As Long) As Long
Public Const GW_CurrhWndNEXT = 2
Public Const GW_CHILD = 5
Public Sub GetProc()
Dim CurrhWnd As Long
Dim lv_WindowTextLength As Long
Dim lv_Parent As Long
Dim lv_Process As String
CurrhWnd = GetDesktopWindow()
CurrhWnd = GetWindow(CurrhWnd, GW_CHILD)
While CurrhWnd
lv_Parent = GetParent(CurrhWnd)
lv_WindowTextLength = GetWindowTextLength(CurrhWnd)
lv_Process = Space(lv_WindowTextLength + 1)
lv_WindowTextLength& = GetWindowText(CurrhWnd, lv_Process, (lv_WindowTextLength + 1))
lv_Process = Left(lv_Process, Len(lv_Process) - 1)
If Len(lv_Process) > 0 Then
If IsWindowVisible(CurrhWnd) Then
Print lv_Process
End If
End If
CurrhWnd = GetWindow(CurrhWnd, GW_CurrhWndNEXT)
Wend
End Sub
Subject: list of all apps running on the computer
Even the list that TaskMan gives you wouldn’t be of much help since it only lists the browser tab currently in focus in each browser instance.
Subject: RE: list of all apps running on the computer
I can live with that condition. Will be grateful for any guidance. Thanks.
Subject: RE: list of all apps running on the computer
You’ll probably have better luck posting in some MS forums - since the OS is where the apps run, figuring out what’s going on would be more at the Win API level.
You might also try searching here and in the 4/5 forum for Win API posts - you might get lucky.
HTH and if you get something working, be sure to post it back here.
Doug