*** AppLister.prg #Define SW_HIDE 0 #Define SW_SHOWNORMAL 1 #Define SW_SHOWMINIMIZED 2 #Define SW_SHOWMAXIMIZED 3 #Define TH32CS_SNAPHEAPLIST 0x00000001 #Define TH32CS_SNAPPROCESS 0x00000002 #Define TH32CS_SNAPTHREAD 0x00000004 #Define TH32CS_SNAPMODULE 0x00000008 #Define TH32CS_SNAPALL 0x0000000F #Define TH32CS_INHERIT 0x80000000 #Define MAX_MODULE_NAME32 255 #Define MAX_PATH 260 #Define SIZEOF_PE32 296 #Define SIZEOF_ME32 548 #Define WM_CLOSE 0x0010 #Define WM_QUERYENDSESSION 0x0011 #Define WM_QUIT 0x0012 ** Sample usage lnOldBehavior = SET("EngineBehavior") Set EngineBehavior 70 oAppsLister = Newobject('AppsLister','appLister.prg') oAppsLister.GetAppsRunning('MyCursor') SET ENGINEBEHAVIOR m.lnOldBehavior Select myCursor Browse for !Empty(exeName) Define Class AppsLister As Line Dimension arrDLLs[1] Me32Structure = '' Pe32Structure = '' ProcListCursor = Sys(2015) ModuleListCursor = Sys(2015) AppsListCursor = Sys(2015) Procedure Init Local Array arrDLLs[1] Adlls(arrDLLs) && Save defined DLLs Acopy(arrDLLs,This.arrDLLs) This.InitDLLs() && Declare DLLs This.Me32Structure = This.Int2Str(SIZEOF_ME32) + ; Replicate(Chr(0), SIZEOF_ME32-4) This.Pe32Structure = This.Int2Str(SIZEOF_PE32) + ; Replicate(Chr(0), SIZEOF_PE32-4) This.CreateCursors() Endproc Procedure CreateCursors Create Cursor (This.ModuleListCursor) ; (ProcessID i, szModule m, szExeFile m) Create Cursor (This.ProcListCursor) ; (ProcessID i,; cntThreads i,; parentPID i,; szExeFile m) Create Cursor (This.AppsListCursor) ; (wHwnd i,Pid i, Tid i,ClassName c(100),wCaption c(200)) Endproc Procedure RemoveCursors Use In (This.ModuleListCursor) Use In (This.ProcListCursor) Use In (This.AppsListCursor) Endproc Procedure GetDesktopWindows2Array Lparameters taArray tcCursorName = Iif(Empty(m.tcCursorName), 'crsDesktop', m.tcCursorName) Local tempHwnd Create Cursor (m.tcCursorName) (nHwnd i) tempHwnd = GetActiveWindow() && Start from active Do While !Empty(tempHwnd) If IsWindowVisible(tempHwnd) = 1 And GetWindow(tempHwnd, GW_OWNER) = 0 Insert Into (m.tcCursorName) Values (tempHwnd) Endif tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT) Enddo Select nHwnd From (m.tcCursorName) Into Array taArray Use In (m.tcCursorName) Endproc Procedure GetAppsRunning Lparameters tcCursorName, tlDestroyOldCursor If m.tlDestroyOldCursor This.CreateCursors() Endif Set Library To Set Library To "AppLauncher.fll" Additive DeskTopWindows2Array('arrDesktop') Set Library To For Each m.nHwnd In arrDesktop Store Replicate(Chr(0),200) To lpClassName, ctitle_bar lpdwProcessId = 0 lnThreadID=GetWindowThreadProcessId(m.nHwnd, @lpdwProcessId) nBufLen = GetClassName(m.nHwnd,@lpClassName,200) rettext = GetWindowText(m.nHwnd, @ctitle_bar, 200) Insert Into (This.AppsListCursor) ; VALUES (m.nHwnd,m.lpdwProcessId,m.lnThreadID,; substr(m.lpClassName,1,m.nBufLen), ; LEFT(m.ctitle_bar, m.rettext)) Endfor This.GetProcessList() Select ap.*,; pl.cntThreads, pl.parentPID, ; Nvl(ml.szModule,pl.szExeFile) As 'ModuleName', ; Nvl(ml.szExeFile,'') As exename ; from (This.AppsListCursor) ap ; INNER Join (This.ProcListCursor) pl On pl.ProcessID = ap.Pid ; left Join (This.ModuleListCursor) ml On pl.ProcessID = ml.ProcessID ; into Cursor __applst__ ; nofilter Select * From __applst__ ; union ; Select * From __applst__ ; into Cursor (m.tcCursorName) ; nofilter Use In '__applst__' Endproc Procedure GetModulesRunning Lparameters tcCursorName tcCursorName = Iif(Empty(m.tcCursorName),'Modules',m.tcCursorName) This.GetProcessList() Select pl.ProcessID, pl.cntThreads, pl.parentPID, ; Nvl(ml.szModule,pl.szExeFile) As 'ModuleName', ; Nvl(ml.szExeFile,'') As exename ; from (This.ProcListCursor) pl ; left Join (This.ModuleListCursor) ml On pl.ProcessID = ml.ProcessID ; into Cursor (m.tcCursorName) ; nofilter Endproc Procedure InitDLLs && Declare DLLs Declare Sleep In WIN32API Integer dwMillis Declare Integer GetActiveWindow In Win32API Declare short IsWindowVisible In WIN32API Integer HWnd Declare Integer GetWindow In Win32API; INTEGER HWnd, Integer dflag Declare Integer GetWindowText In Win32API ; INTEGER HWnd, String @lptstr, Integer cbmax Declare Integer GetClassName In WIN32API ; Integer HWnd, String @cClass, Integer nMaxBuffer Declare Integer GetWindowThreadProcessId In win32API ; Integer HWnd, Integer @lpdwProcessId Declare Integer CloseHandle In win32API Integer hObject Declare Integer CreateToolhelp32Snapshot In win32API ; INTEGER dwFlags, Integer th32ProcessID Declare Integer Process32First In win32API ; INTEGER hSnapshot, String @ lppe Declare Integer Process32Next In win32API ; INTEGER hSnapshot, String @ lppe Declare Integer Module32First In win32API ; INTEGER hSnapshot, String @ lpme Declare Integer Module32Next In win32API ; INTEGER hSnapshot, String @ lpme Declare RtlMoveMemory In WIN32API ; INTEGER @DestNumeric, ; STRING @pVoidSource, ; INTEGER nLength Declare Integer SendMessage In user32.Dll ; integer HWnd,; integer Msg, ; integer wParam, ; integer Lparam Declare Integer PostMessage In user32.Dll ; integer HWnd,; integer Msg, ; integer wParam, ; integer Lparam Endproc Procedure Destroy Local lnDLLs Local Array arrDLLs[1] lnDLLs = Adlls(arrDLLs) && Get current DLLs For ix=1 To m.lnDLLs If Empty(This.arrDLLs) Or ; Ascan(This.arrDLLs,arrDLLs[m.ix,2],1,-1,2,1+2+4+8) = 0 Clear Dlls &arrDLLs[m.ix,2] Endif Endfor This.RemoveCursors() Endproc Procedure GetProcessModule Lparameters tnPID Local hModuleSnap, me32 hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m.tnPID) If hModuleSnap < 0 Return .F. Endif me32 = This.Me32Structure lSuccess = ( Module32First(hModuleSnap, @me32) # 0) This.MODULEENTRY32_ToCursor(m.me32) CloseHandle (hModuleSnap) Endproc Function GetProcessList Local hProcessSnap, pe32, lSuccess hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) pe32 = This.Pe32Structure * Walk the snapshot of the processes * and for each process, get module info lSuccess = ( Process32First(hProcessSnap, @pe32) # 0 ) Do While m.lSuccess m.th32ProcessID = This.PROCESSENTRY32_ToCursor(m.pe32) This.GetProcessModule(m.th32ProcessID) lSuccess = ( Process32Next(hProcessSnap, @pe32) # 0) Enddo CloseHandle (m.hProcessSnap) Endproc Procedure MODULEENTRY32_ToCursor Lparameters tcBuffer Local ProcessID, szModule, szExeFile With This m.ProcessID = .Substr2Num(m.tcBuffer,9,4) m.tcBuffer = Substr(m.tcBuffer,33) m.szModule = Left(m.tcBuffer,At(Chr(0),m.tcBuffer)-1) m.tcBuffer = Substr(m.tcBuffer,256+1) m.szExeFile = Left(m.tcBuffer,At(Chr(0),m.tcBuffer)-1) Insert Into (.ModuleListCursor) ; (ProcessID,szModule,szExeFile) Values ; (m.ProcessID,m.szModule,m.szExeFile) Endwith Endproc Procedure PROCESSENTRY32_ToCursor Lparameters tcBuffer Local ProcessID, cntThreads, parentPID, szExeFile With This m.ProcessID = .Substr2Num(m.tcBuffer,9,4) m.cntThreads = .Substr2Num(m.tcBuffer,21,4) m.parentPID = .Substr2Num(m.tcBuffer,25,4) m.tcBuffer = Substr(m.tcBuffer,37) m.szExeFile = Left(m.tcBuffer,At(Chr(0),m.tcBuffer)-1) Insert Into (.ProcListCursor) ; (ProcessID, cntThreads, parentPID, szExeFile) ; values ; (m.ProcessID, m.cntThreads, m.parentPID, m.szExeFile) Endwith Return m.ProcessID Endproc Procedure Substr2Num Lparameters tcStr, tnStart, tnSize Return This.Str2Num(Substr(m.tcStr, m.tnStart, m.tnSize), m.tnSize) Endproc Procedure Str2Num Lparameters tcStr,tnSize Local m.lnValue m.lnValue=0 RtlMoveMemory(@lnValue, m.tcStr, m.tnSize) Return m.lnValue Endproc Procedure Int2Str Lparameters tnValue, tnSize Local ix, lcReturn m.tnSize = Iif(Empty(m.tnSize),4,m.tnSize) lcReturn = '' For ix=1 To m.tnSize m.lcReturn = m.lcReturn + ; Chr(Bitand(Bitrshift(m.tnValue, (m.ix-1)*8),0xFF)) Endfor Return m.lcReturn Endproc Procedure CloseApplication(tnHwnd) PostMessage(m.tnHwnd,WM_CLOSE,0,0) Endproc Enddefine