Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Killing the DOS window, Part II.
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Fonctions Windows API
Divers
Thread ID:
00502520
Message ID:
00502962
Vues:
19
This message has been marked as a message which has helped to the initial question of the thread.
Hi!

>Hi Vlad,
>
>>Hi!
>>
>>Only one instance of NTWDM could be in the memory. If you kill it, you will kill all DOS or Windows 3.* programs currently running.
>>
>
>That does not seem to be correct (at least not for Windows 2000). There is an instance of NTVDM for every DOS window open and I have to loop through them to destroy them one by one.
>

Well, its true for NT. Maybe need to play around parent/child process here?

>>
>>There are special API functions for DOS programs that are located in the separate DLL. I do not know details, but you can try to search from this side. Try also to send this to some other forums that are more related to API functions and low-level programming for Windows (For example, C++ forums).
>>
>>I can also post a sample of correct killing of windows application, but I did not tried it with DOS program (just to compare with your code), if you want.
>
>
>I would like to see this. For now I used enumproc.dll from Downloads section and modified code of the sample call.
>
>

Well, look to following procedure I have made. I don't know all this stuff well, but at least it worked and tested a lot in use by automation service applications.
*******************************************************************************
***** KillApp ****************************************************************
* Reliable procedure of shutdown of application. Tries to shutdown application by normal way
* sending WM_Quit event to its thread. If this will not help within 5 seconds (or specified),
* application will be terminated by API TerminateProcess function
*  Parameters:
* pnHWND				- main Window handle
* plKillImmediate		- if .T., application will be killed without any waiting or messages sending. Next two parameters will be ignored in this case
* plWaitShutdown		- if .T., procedure will wait max.10 seconds until application shutdown.
* plKillWhenNoShutdown  - if .T., App will be killed anyway when shutdown time passed and App still in memory
* pnShutdownTimeOut		- optional, number of miliseconds to wait until application shutdown by normal way. Between 100 and 60000.
* pnProcessID			- optional, ID of process to be killed. Will be used if main window already does not exists (some App crashes causes such situation)
* pcProcessCreationTime	- optional, process creation time to verify if passed process ID is not an ID of another new process

PROCEDURE KillApp
LPARAMETER pnHWND, plKillImmediate, plWaitShutdown, plKillWhenNoShutdown, pnShutdownTimeOut, pnProcessID, pcProcessCreationTime

IF !VARTYPE(m.pnShutdownTimeOut) == "N"
	m.pnShutdownTimeOut = 5000
ELSE
	IF m.pnShutdownTimeOut < 100
		m.pnShutdownTimeOut = 100
	ENDIF
	IF m.pnShutdownTimeOut > 60000
		m.pnShutdownTimeOut = 60000
	ENDIF
ENDIF

DECLARE INTEGER PostThreadMessage IN Win32API INTEGER Hthrd, INTEGER nMessage, short Param1, LONG Param2
DECLARE INTEGER GetWindowThreadProcessId IN Win32API INTEGER HWND, INTEGER @pID
DECLARE INTEGER TerminateProcess IN Win32API INTEGER PID, INTEGER TermCode
DECLARE INTEGER OpenProcess IN Win32API INTEGER fdwAccess, INTEGER fInherit, INTEGER IDProcess
DECLARE INTEGER Sleep IN Win32API INTEGER cMilliseconds
DECLARE INTEGER GetProcessTimes IN Win32API INTEGER HProc, STRING @lpCreation, STRING @lpExit, STRING @lpKernel, STRING @lpUser

LOCAL nTries, nThreadID, nProcessID
m.nProcessID = 0
m.nThreadID = GetWindowThreadProcessId(m.pnHWND,@m.nProcessID)
IF m.nThreadID = 0 OR m.nProcessID = 0
	IF VARTYPE(m.pnProcessID) == "N"
		* check if process exists in memory and creation time is same
		LOCAL lcTime, rrr
		m.lcTime = SPACE(8)
		m.rrr = SPACE(8)
		IF GetProcessTimes(OpenProcess(PROCESS_QUERY_INFORMATION, 0, m.pnProcessID),@m.lcTime,@m.rrr,@m.rrr,@m.rrr)>0
			IF m.lcTime == m.pcProcessCreationTime
				m.nProcessID = m.pnProcessID
				m.plKillImmediate = .T.
			ELSE
				RETURN
			ENDIF
		ELSE
			RETURN
		ENDIF
	ELSE
		* just exit if App already released
		RETURN
	ENDIF
ENDIF

IF !m.plKillImmediate
	* try to close main App window by sending WM_Quit event just into its thread
	m.nTries = m.pnShutdownTimeOut/10
	DO WHILE m.nTries > 0
		IF PostThreadMessage(m.nThreadID, WM_QUIT, 0, 0) > 0
			m.nThreadID = GetWindowThreadProcessId(m.pnHWND,@m.nProcessID)
			IF m.nThreadID = 0 OR m.nProcessID = 0
				* just exit if App released
				RETURN
			ENDIF
		ELSE
			* check if App is in memory
			m.nThreadID = GetWindowThreadProcessId(m.pnHWND,@m.nProcessID)
			IF m.nThreadID = 0 OR m.nProcessID = 0
				RETURN
			ENDIF
			* otherwise, kill it, because it does not respond to messages
			m.nTries = 0
			m.plKillWhenNoShutdown = .T.
		ENDIF

		Sleep(10)
		m.nTries = m.nTries - 1
	ENDDO

	IF !m.plKillWhenNoShutdown
		RETURN
	ENDIF
ENDIF

* if we're here, then we just need kill it
TerminateProcess(OpenProcess(PROCESS_TERMINATE,0,m.nProcessID),-1)

RETURN
>
>>
>>>Hi All,
>>>
>>>I managed to be able to kill the FoxPro DOS application running in a DOS window.
>>>But, there is one problem. I can find the window handle by the window name. I can find the process handle related to the DOS window name. That process handle points me to CMD.EXE, and if I try to kill it, nothing happens to actual DOS window, despite the return code from TerminateProcess API function is 1. In order to kill the real DOS process I have to kill the related ntvdm.exe.
>>>
>>>So, the question is, how I can find the ntvdm.exe process which is related to corresponding CMD.EXE? If there is more than one DOS window, how do I know which ntvdm.exe corresponds to the certain window name?
>>>
>>>Of course I can just loop through all ntvdm.exe instances and kill them all, but that would be overkill... :)
Vlad Grynchyshyn, Project Manager, MCP
vgryn@yahoo.com
ICQ #10709245
The professional level of programmer could be determined by level of stupidity of his/her bugs

It is not appropriate to say that question is "foolish". There could be only foolish answers. Everybody passed period of time when knows nothing about something.
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform