' This program was inspired by the excellent routines provided by
' Graham McPhee (many thanks), see this link:
' http://www.powerbasic.com/support/pb...ad.php?t=37879
'
' It may be a surprise to you to see how many processes are actually
' running on your computer. You may even find that the same process
' is running in more than one instance.
'
' Best regards,
'
' Erik -------------- 30 November, 2008
'
' P.S. 6 December, 2008: included information about size of file.
Code:
' Which Processes Are Running On My Computer?
'
' This program was inspired by the excellent routines provided by
' Graham McPhee (many thanks), see this link:
' http://www.powerbasic.com/support/pbforums/showthread.php?t=37879
'
' It may be a surprise to you to see how many processes are actually
' running on your computer. You may even find that the same process
' is running in more than one instance.
'
' Best regards,
'
' Erik -------------- 30 November, 2008
'
' P.S. 6 December, 2008: included information about size of file.
#COMPILE EXE
#DIM ALL
'
#INCLUDE "WIN32API.INC"
'
%IDD_DIALOG1                    =  100
%IDC_BUTTON1_EXIT               = 1001
%IDC_LISTBOX1                   = 1002
'
'  Processes running . PB_Processes.inc (Provided by Graham McPhee - Thanks!)
'
DECLARE FUNCTION EnumProcesses (lpidProcess AS DWORD, BYVAL cb AS DWORD, cbNeeded AS DWORD) AS LONG
DECLARE FUNCTION GetModuleFileNameEx (BYVAL hProcess AS DWORD, BYVAL hModule AS DWORD, ModuleName AS ASCIIZ, nSize AS DWORD) AS DWORD
DECLARE FUNCTION EnumProcessModules (BYVAL hProcess AS DWORD, BYREF lphModule AS DWORD, BYVAL cb AS DWORD, cbNeeded AS DWORD) AS LONG
'
TYPE PROCESSENTRY32
   dwSize AS DWORD
   cntUsage AS DWORD
   th32ProcessID AS DWORD          ' This process
   th32DefaultHeapID AS LONG PTR
   th32ModuleID AS DWORD           ' Associated exe
   cntThreads AS DWORD
   th32ParentProcessID AS DWORD    ' This process's parent process
   pcPriClassBase AS LONG          ' Base priority of process threads
   dwFlags AS DWORD
   szExeFile AS ASCIIZ * %MAX_PATH
END TYPE
'
FUNCTION ListAllProcesses(BYVAL hDlg AS DWORD) AS LONG
'
    DIM Reply AS STRING
    DIM lngR AS INTEGER
    DIM strModule AS STRING
    DIM strExe AS STRING
    DIM f AS STRING
    DIM DirDataVar AS DIRDATA
    '
    CALL EnumModules(Reply)  ' pick up the processes in a string
    '
    FOR lngR = 1 TO PARSECOUNT(Reply,$CRLF)
        strModule = PARSE$(Reply,$CRLF,lngR)
        strExe = PARSE$(strModule,"|",2) ' path and filename
        f = DIR$(strExe, TO DirDataVar)  ' get file data including file size
        IF DirDataVar.FileSizeLow > 0 THEN LISTBOX ADD hDlg, %IDC_LISTBOX1, strExe + "     Size ="+STR$(DirDataVar.FileSizeLow) + " Bytes"
    NEXT lngR
    '
    FUNCTION = 1
'
END FUNCTION
'
SUB EnumModules(Reply AS STRING) ' Provided by Graham McPhee
  LOCAL Proc AS PROCESSENTRY32
  LOCAL cb AS DWORD, cbNeeded AS DWORD
  LOCAL i AS LONG, j AS LONG, nModules AS LONG, nProcesses AS LONG, hProcess AS DWORD, lResult AS LONG
  LOCAL hPsApiDll AS DWORD, hEnumProcesses AS DWORD, hGetModuleFileNameEx AS DWORD, hEnumProcessModules AS DWORD
  LOCAL SizeOfFile AS DWORD
  hPsApiDll = GetModuleHandle("psApi.dll")
  IF hPsApiDll = 0 THEN hPsApiDll = LoadLibrary("psApi.dll")
    hEnumProcesses = GetProcAddress(hPsApiDll, "EnumProcesses")
    hGetModuleFileNameEx = GetProcAddress(hPsApiDll, "GetModuleFileNameExA")
    hEnumProcessModules = GetProcAddress(hPsApiDll, "EnumProcessModules")
    cb = 100
    DO
      REDIM ProcessIDs(1 TO cb / 4) AS DWORD
      CALL DWORD hEnumProcesses USING EnumProcesses (ProcessIDs(1), cb, cbNeeded) TO lResult
      IF cb > cbNeeded THEN EXIT DO
      cb = cb * 2
    LOOP
    '
    Reply = ""
    nProcesses = cbNeeded / 4
    FOR i = 1 TO nProcesses
       hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION OR %PROCESS_VM_READ OR _
                              %PROCESS_CREATE_THREAD OR %PROCESS_VM_OPERATION OR _
                              %PROCESS_VM_WRITE, %False, ProcessIDs(i))
      IF hProcess THEN
        LOCAL CmdLine AS STRING
        '
        cb = 100
        DO
          REDIM Modules(1 TO cb / 4) AS DWORD
          CALL DWORD hEnumProcessModules USING _
          EnumProcessModules (hProcess, Modules(1), cb, cbNeeded) TO lResult
          IF lResult = 0 THEN cbNeeded = 0: EXIT DO
          IF cb > cbNeeded THEN EXIT DO ELSE cb = cb * 2
        LOOP
        IF cbNeeded >= 4 THEN
          CALL DWORD hGetModuleFileNameEx USING GetModuleFileNameEx _
            (hProcess, Modules(1), Proc.szExeFile, SIZEOF(Proc.szExeFile)) TO lResult
            IF lResult THEN Reply = Reply + STR$(ProcessIDs(i))+ "|" + Proc.szExeFile + "|" + $CRLF
        END IF
       CloseHandle hProcess
     END IF
  NEXT nProcesses
END SUB
'
CALLBACK FUNCTION ShowDIALOG1Proc()
    SELECT CASE AS LONG CBMSG
        CASE %WM_INITDIALOG
            ListAllProcesses(CBHNDL)
        CASE %WM_COMMAND
            SELECT CASE AS LONG CBCTL
                CASE %IDC_BUTTON1_EXIT
                    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN DIALOG END CBHNDL
            END SELECT
    END SELECT
END FUNCTION
'
FUNCTION PBMAIN()
    LOCAL lRslt AS LONG
    LOCAL hDlg  AS DWORD
    DIALOG NEW %HWND_DESKTOP, "Which Processes Are Running On My Computer?", , _
        , 451, 193, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION _
        OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE _
        OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
        %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
        %WS_EX_RIGHTSCROLLBAR, TO hDlg
    CONTROL ADD LISTBOX, hDlg, %IDC_LISTBOX1, , 16, 12, 420, 140, %WS_CHILD _
        OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_HSCROLL OR %WS_VSCROLL OR _
        %LBS_SORT OR %LBS_NOTIFY, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _
        %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    CONTROL ADD BUTTON,  hDlg, %IDC_BUTTON1_EXIT, "E&xit", 392, 164, 44, 16
    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    FUNCTION = lRslt
END FUNCTION