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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

get snapshot of processes running xp 2000 (not NT)

Status
Not open for further replies.
Sep 17, 2001
673
US
** The following program will take a snapshot of current processes running and insert into a cursor called 'Cprocces_info'. Also includes other helpful info about processes for use with other functions I have not added on yet. I am using it to disallow running of additional instances of a program called xxxx*.exe I could not find a program that would do this.


** Program: gets processes running on system
#DEFINE TH32CS_SNAPPROCESS 0x00000002

LOCAL lcProcessName, lnBufSize, lcProcInfo, lnResult, lnProcID, th32DefaultHeapID
LOCAL cntUsage, th32ProcessID, th32ModuleID, cntThreads, th32ParentProcessID, pcPriClassBase, dwFlags, szExeFile

CREATE CURSOR Cprocess_info(szExeFile C(50),cntUsage INT, th32ProcessID INT, th32DefaultHeapID INT,;
th32ModuleID INT, cntThreads INT, th32ParentProcessId INT, pcPriClassBase INT, ;
dwFlags INT)

&& Declare DLLs needed for the case
DECLARE INTEGER CreateToolhelp32Snapshot IN Kernel32 INTEGER dwFlags, INTEGER th32ProcessID
DECLARE INTEGER Process32First IN kernel32 INTEGER hSnapshot, STRING @lpPE
DECLARE INTEGER Process32Next IN kernel32 INTEGER hSnapshot, STRING @ lpPE
DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject

hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
lnBufSize = 550
lcProcInfo = Num2DWORD(lnBufSize) + REPLICATE(CHR(0), lnBufSize -32)

** ITERATE THROUGH PROCESSES AND INSERT INTO PROCESS INFO CURSOR
lnResult = Process32First(hSnapShot, @lcProcInfo)
*lnProcID = 0
DO WHILE lnResult # 0
m.cntUsage = Buf2DWORD(SUBSTR(lcProcInfo, 5, 4))
m.th32ProcessID = Buf2DWORD(SUBSTR(lcProcInfo, 9, 4))
m.th32DefaultHeapID = Buf2DWORD(SUBSTR(lcProcInfo, 13, 4))
m.th32ModuleID = Buf2DWORD(SUBSTR(lcProcInfo, 17, 4))
m.cntThreads = Buf2DWORD(SUBSTR(lcProcInfo, 21, 4))
m.th32ParentProcessID = Buf2DWORD(SUBSTR(lcProcInfo, 25, 4))
m.pcPriClassBase = Buf2DWORD(SUBSTR(lcProcInfo, 29, 4))
m.dwFlags = Buf2DWORD(SUBSTR(lcProcInfo, 33, 4))
m.szExeFile = STRTRAN(SUBSTR(lcProcInfo,37), CHR(0), "")
INSERT INTO Cprocess_info FROM MEMVAR
lcProcInfo= SUBSTR(lcProcInfo, 1, 36) + REPLICATE(CHR(0), lnBufSize - 36)
lnResult = Process32Next(hSnapShot, @lcProcInfo)
ENDDO


CLEAR DLLS OpenProcess, TerminateProcess, CloseHandle


******************************************************************************************************************************
FUNCTION Buf2DWORD(tcBuffer)
******************************************************************************************************************************
** Function Name : Buf[fer] 2 DWORD
** Purpose :
** Description :
** Parameter(s) : Buffer as a Char*4 string
** Return : DWORD type imitation as LONG INTEGER
** Side Effect(s):
** Notes: :
******************************************************************************************************************************
&& RETURN ASC(SUBSTR(lcBuffer, 1, 1)) + ASC(SUBSTR(lcBuffer, 2, 1)) * 2^8 + ASC(SUBSTR(lcBuffer, 3, 1)) * 2^16 + ASC(SUBSTR(lcBuffer, 4,1)) * 2^24
IF TYPE('tcBuffer') # "C"
RETURN 0
ENDIF

tcBuffer = LEFT(ALLTRIM(tcBuffer), 4)

LOCAL I, lnRet

lnRet = 0
FOR I = 0 TO 3
lnRet = lnRet + ASC(SUBSTR(tcBuffer, I + 1, 1)) * 2^(8 * I)
NEXT I

RETURN lnRet
ENDFUNC
******************************************************************************************************************************

******************************************************************************************************************************
FUNCTION Num2DWORD(tnValue)
******************************************************************************************************************************
** Function Name :
** Purpose :
** Description :
** Parameter(s) :
** Return :
** Side Effect(s):
** Notes: :
******************************************************************************************************************************
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216

LOCAL b0, b1, b2, b3

b3 = INT(tnValue / m2)
b2 = INT((tnValue - b3 * m2) / m1)
b1 = INT((tnValue - b3 * m2 - b2 * m1) / m0)
b0 = MOD(tnValue, m0)
RETURN CHR(b0) + CHR(b1) + CHR(b2) + CHR(b3)
ENDFUNC

*Original source:
*
* END PROGRAM

Regards,

Rob
 
robsuttonjr said:
I am using it to disallow running of additional instances of a program called xxxx*.exe I could not find a program that would do this
You might consider using WMI to achieve this.


You could modify the code in the FAQ Ensuring only one instance of an app using WMI faq184-6206 by using the .Terminate(0) method once you have identified the process.

FAQ184-2483 - answering getting answered.​
Chris [pc2]
PDFcommandertm.net
PDFcommandertm.com
 
As CHris mentionned you will find an example written with WMI here as well in faq184-4140
Function to terminate all instances of a running process.

Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
ReFox XI (www.mcrgsoftware.com)
 
After spending a bit of time building a class around process, thread, and window handling using both the snapshot API and WMI I have to say the WMI method is much cleaner and what I would prefer to see.

As an aside i found that most of my users started the app again because they had minimized it and didn't realize it was already running. I thought it would be better to bring the app to the forefront in the event they tried to launch it again.

As you can see from my comments I lifted the idea from Craig Boyd.

Code:
* PRE:		Arg must be a valid window handle
* POST:		The window whose handle was passed should be the top most window	
* ARGS:		vhWindowHandle; Numeric containing a valid window handle	
* NOTES:	Credit for this idea needs to go to Craig S Boyd ([URL unfurl="true"]http://www.sweetpotatosoftware.com)[/URL] 
*			for his post to : Tek-Tips faq184-4262.  I lifted his concept for this method.  
*			Method attempts to for the passed Window Handle to the top of the window stack.
* CALLS:	A handful of API functions	
* RETURNS:	Boolean indicating if the top window is the handle of the arg passed	
* ALGORITHM:- Get the handle of the current top window (foreground Window)
*			- Check if the foreground window handle matches handle passed
*			- If matches bring the window up
*			- If not
*				- Attach the passed handle to the foreground window's thread
*				- Bring the window to the top
*				- Disconnect our window from the Thread
*		 	- Check to see if it worked and pass back return value

LPARAMETERS vhWindowHandle AS Integer, viFlag AS Integer

ASSERT !EMPTY(vhWindowHandle) MESSAGE "No arg passed to ProcessClass.ShowWindow"

IF !THIS.SuppressDebugs THEN
	DEBUGOUT "     ProcessClass.ShowWindow called"
ENDIF

LOCAL lhForeGroundWindowHandle AS Number, lnForeGroundThreadID AS Number
LOCAL lnTargeWindowThreadID AS Number, llReturn AS Logical, liFlag AS Integer
LOCAL SW_HIDE, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, SW_SHOWNOACTIVATE, SW_SHOW
LOCAL SW_MINIMIZE, SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE, SW_SHOWDEFAULT

DECLARE Long BringWindowToTop In Win32API Long
DECLARE Long ShowWindow In Win32API Long, Long
DECLARE INTEGER GetCurrentThreadId IN kernel32 
DECLARE INTEGER GetWindowThreadProcessId IN user32 INTEGER hWnd, INTEGER @ lpdwProcId  
DECLARE INTEGER GetCurrentThreadId IN kernel32      
DECLARE INTEGER AttachThreadInput IN user32 INTEGER idAttach, INTEGER idAttachTo, INTEGER fAttach
DECLARE INTEGER GetForegroundWindow IN user32  
DECLARE INTEGER SetForegroundWindow IN user32 INTEGER hwnd 
	
SW_HIDE 			= 0					&& Constants for ShowWindow
SW_NORMAL 		= 1
SW_SHOWMINIMIZED 	= 2
SW_SHOWMAXIMIZED 	= 3
SW_SHOWNOACTIVATE 	= 4
SW_SHOW 		= 5
SW_MINIMIZE 		= 6
SW_SHOWMINNOACTIVE 	= 7
SW_SHOWNA 		= 8
SW_RESTORE 		= 9
SW_SHOWDEFAULT 		= 10
llReturn 		= .F.

liFlag 	= IIF(EMPTY(viFlag), SW_NORMAL, CAST( viFlag AS Integer) )

lhForeGroundWindowHandle = GetForegroundWindow() 
lnForeGroundThreadID 	 = GetWindowThreadProcessId( lhForeGroundWindowHandle, 0 ) 
lnTargeWindowThreadID 	 = GetWindowThreadProcessId( vhWindowHandle, 0 ) 
    
IF lnForeGroundThreadID == lnTargeWindowThreadID THEN
	BringWindowToTop( vhWindowHandle )
	SetForegroundWindow(vhWindowHandle)
 *   ShowWindow( vhWindowHandle, liFlag  )  
ELSE
	AttachThreadInput( lnForeGroundThreadID, lnTargeWindowThreadID, .T. )
    BringWindowToTop( vhWindowHandle )
   	SetForegroundWindow(vhWindowHandle)
*    ShowWindow( vhWindowHandle, liFlag )   
    AttachThreadInput( lnForeGroundThreadID, lnTargeWindowThreadID, .F. )
ENDIF       

lhForeGroundWindowHandle = GetForegroundWindow() 
IF lhForeGroundWindowHandle == vhWindowHandle THEN
	llReturn = .T.
ENDIF
   
CLEAR DLLS BringWindowToTop, ShowWindow, GetCurrentThreadId, GetWindowThreadProcessId
CLEAR DLLS AttachThreadInput, GetForegroundWindow, GetCurrentThreadId, SetForegroundWindow 

RETURN llReturn

I appologize for being too lazy to adjust the formatting to fit the frame.

Ralph Kolva
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top