



class Files_start_Dlg : public CDialog

{



//...





private:



	///////////////////////////////////////////////////////////////////////////////////////

	// jeto 2 vozmozhnosti poluchit' ProcessID: kakuju ispol'zovat' - kazhdyj reshaet sam:

	///////////////////////////////////////////////////////////////////////////////////////



	// vozvrashhaet ID processa

	bool getProcessId ( const char *pProgrName_in, DWORD *pth32ProcessID_out, bool bWithTraces = true );

	// vozvrashhaet ID processa i ID threada

	bool GetProcessByExeName ( CString& ExeName, DWORD& dwThreadId, DWORD& dProcId );



	// raznye vozmozhnosti ubit' zapushhennyj process

	void KillProcess_taskkill(const char* const pExeName);

	void KillProcess_sendMsg ( CString& sProcessName);

	void KillProcess_terminateProc ( const CString& sProcessName);

	void KillProcess_createTerminateProc ( const CString& sProcessName);

	bool st_RunProcessAndWaitWhenDone( const char* szApplicationName, 

							const char* szCommandLine_i = 0,

							const char* szCurrentDirectory = 0, DWORD dwdTimeOut_i = -1 );



	// nahodit put' sistemnogo kataloga

	CString GetSystemPATH__();

	



};



// vse perechislennye vyzovy funkcij rabotajut, prosto 

// sootvetstvenno v funkcii mozhet ispol'zovat'sja tol'ko odin iz sposobov ;-)

// pojetomu ostal'nye zakommentirovany

void Files_start_Dlg::OnExeStop() 

{

/*

	// tak mozhno v odnom processa startovat', a zatem ubit' drugoj process

	CString sProcessName1 ("E:\\irina\\fs.exe");

	KillProcess_createTerminateProc ( sProcessName1 );





	// tak mozhno ubit' process, kotoryj byl zapushhen iz drugogo prilozhenija

	// variant 1:

	CString sProcessName_msg ( "FS" );

	KillProcess_terminateProc (sProcessName_msg);



	// variant 2:

	CString sProcessName ( "FS" );

	KillProcess_sendMsg (sProcessName);

*/

	// variant 3

	KillProcess_taskkill ( sProcessName );

}





/////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////

// varianty dlja kill process:

///////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////





///////////////////////////////////////////////////////////////

// s pomoshh'ju taskkill.exe

///////////////////////////////////////////////////////////////

void Files_start_Dlg::KillProcess_taskkill(const char* const pExeName)

{

	DWORD dwThreadId, dProcId;

	CString ExeName = pExeName;

	if(!GetProcessByExeName ( ExeName, dwThreadId, dProcId ) ) return;



	HANDLE hpr=0;

	hpr=::OpenProcess ( PROCESS_TERMINATE, 0, dProcId );



	if( hpr )

	{

		CString txt, sTaskKill ("taskkill.exe");



		// ne vsegda taskkill.exe nahoditsja v C:\\windows\\system32, pojetomu dlja gibkosti 

		// nashejj programmy sistemnyj put' nahodim programmnym putem

		CString sSysPath = GetSystemPATH__();



		//killen das Process und alle Children-Processes

		txt.Format( " /c %s\%s /pid %d /f /t",sSysPath, sTaskKill, dProcId );

		

		st_RunProcessAndWaitWhenDone(sSysPath + "cmd.exe", txt);



	}

	else

	{

		DWORD nErr = GetLastError();

	}



	::TerminateProcess(hpr,0);

	::CloseHandle(hpr);

	

	return;

}





////////////////////////////////////////

// kill a process with taskkill.exe

////////////////////////////////////////

bool Files_start_Dlg::st_RunProcessAndWaitWhenDone ( const char* szApplicationName,

													 const char* szCommandLine_i,

													 const char* szCurrentDirectory,

													 DWORD dwdTimeOut_i)

{



	STARTUPINFO	StartupInfo;

	PROCESS_INFORMATION ProcessInfo;

	DWORD dwRetValue;



	::memset ( &StartupInfo, 0, sizeof(StartupInfo) );

	StartupInfo.cb = sizeof ( StartupInfo );



	CString csCommandLine = szCommandLine_i; //jeto objazatel'no, inache isportitsja soderzhimoe stroki szCommandLine_i!!!



	if( !::CreateProcess(

		szApplicationName, (char*)(const char*)csCommandLine,

		0, 0, 0, NORMAL_PRIORITY_CLASS, 0, szCurrentDirectory,

		&StartupInfo, &ProcessInfo))

	{

		// oshibka - proverjaem

		DWORD dwdErr=GetLastError(); 

		return false;

	}

	else

	{

		::CloseHandle ( ProcessInfo.hThread );

		::WaitForSingleObject ( ProcessInfo.hProcess, dwdTimeOut_i );

		::GetExitCodeProcess ( ProcessInfo.hProcess, &dwRetValue );

		::CloseHandle ( ProcessInfo.hProcess);

	}

	return true;

}





///////////////////////////////////////////////////////////////

// terminate process. the process was created in other program

///////////////////////////////////////////////////////////////

void Files_start_Dlg::KillProcess_sendMsg ( CString& sProcessName)

{

	DWORD dwThreadId, dProcId; 

	CWnd* pWnd = FindWindow ( NULL, sProcessName);

	

	// ishhem ID processa

	GetProcessByExeName ( sProcessName, dwThreadId, dProcId );



	// poluchaemm handle processa

	HANDLE hProc = ::OpenProcess (PROCESS_ALL_ACCESS, false, dProcId);

	if ( hProc )

	{

		UINT uExitCode = NO_ERROR;



		// jeto ne ochen' korrektnyj sposob zavershenija processa

		//BOOL bIsTerminated = TerminateProcess (hProc, uExitCode );

		

		// pojetomu tak luchshe (hotja v principe oba imejut mesto byt')

		::SendMessage (pWnd->m_hWnd, WM_CLOSE, 0, 0); 



		CloseHandle (hProc);

	}

}







///////////////////////////////////////////////////////////////

// terminate process. the process was created in other program (application)

///////////////////////////////////////////////////////////////

void Files_start_Dlg::KillProcess_terminateProc ( const CString& sProcessName)

{

	DWORD nProcessId = 0;



	getProcessId ( "FS.exe", &nProcessId, false);



	HANDLE hProc = ::OpenProcess (PROCESS_ALL_ACCESS, false, nProcessId);

	if ( hProc )

	{

		UINT uExitCode = NO_ERROR;

		BOOL bIsTerminated = TerminateProcess (hProc, uExitCode );

		CloseHandle (hProc);

	}

}





/////////////////////////////////////////////////

// create and terminate process in one program

/////////////////////////////////////////////////

void Files_start_Dlg::KillProcess_createTerminateProc ( const CString& sProcessName)

{

	STARTUPINFO cif;

	ZeroMemory(&cif,sizeof(STARTUPINFO) );

	PROCESS_INFORMATION pi;



	if ( CreateProcess(sProcessName,NULL,NULL,NULL,FALSE,NULL,NULL,NULL,&cif,&pi) )

	{

		TerminateProcess(pi.hProcess,NO_ERROR); 

	}

}







CString Files_start_Dlg::GetSystemPATH__()

{

	CString result = "";

	int len = MAX_PATH + 1;

	char* chSys = new char [len];



	::memset( chSys, 0, len );



	if( !::GetSystemDirectory (chSys, len) ) return "";



	result = chSys;

	result += "\\";



	delete [] chSys;

	chSys=0;



	return result;

}





////////////////////////////////////////

// get process id and thread id

////////////////////////////////////////

bool Files_start_Dlg::GetProcessByExeName ( CString& ExeName, DWORD& dwThreadId, DWORD& dProcId )

{

	CWnd* pWnd = FindWindow ( NULL, ExeName);

	dwThreadId = GetWindowThreadProcessId (pWnd->m_hWnd, &dProcId);



	return true;

}









////////////////////////////////////////

// get process id (other way)

////////////////////////////////////////



// jeta funkcija ishhet ne tol'ko process id, no i vse ego podmoduli. A vozvrashhaet tol'ko processId ( ona byla prosto bystro podognana dlja jetogo primera )

// i eshhe - zdes' zakommentirovany vse vyzovy GetDlgItem(), t.k. oni ne budut rabotat' iz-za otsutstvija polnogo proekta s resursami. 



bool Files_start_Dlg::getProcessId ( const char *pProgrName_in, DWORD *pth32ProcessID_out, 

									 bool bWithTraces )

{

    HANDLE         hProcessSnap = NULL; 

    BOOL           bRet      = FALSE; 

    PROCESSENTRY32 pe32      = {0}; 

    char           sBuf[10000], sText[10000] ;

    CString        sEditText = ""; 



    char buf[100];

    DWORD th32ProcessID = 0;

 

    //  Take a snapshot of all processes in the system. 

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 



    if (hProcessSnap == INVALID_HANDLE_VALUE) 

        return (FALSE); 

 

    //  Fill in the size of the structure before using it. 

    pe32.dwSize = sizeof(PROCESSENTRY32); 

 

    //  Walk the snapshot of the processes, and for each process, 

    //  display information. 

    if (Process32First(hProcessSnap, &pe32)) 

    { 

        //DWORD         dwPriorityClass; 

        BOOL          bGotModule = FALSE; 

        MODULEENTRY32 me32       = {0}; 

        HANDLE        hModSnap = NULL;



		//GUITHREADINFO guiThr   = {0};

        BOOL          bGotGuiThread = FALSE; 

        

        THREADENTRY32 thr32   = {0};

        HANDLE        hThrSnap = NULL;

        BOOL          bGotThread = FALSE; 



        do 

        { 

            strcpy(buf, pe32.szExeFile);

            th32ProcessID = pe32.th32ProcessID; 



			// test the name of the process

			if (0 == strcmp(buf, pProgrName_in))

			{

				// only for test!

				if ( bWithTraces )

				{

					sprintf(sBuf, "ProcessName = %s	processID = %d \r\n", buf, th32ProcessID);



					//GetDlgItem(IDC_PROC_LIST_LIST)->GetWindowText(sEditText);

					strcpy(sText, sEditText);

					strcat(sText, sBuf);



					//GetDlgItem(IDC_PROC_LIST_LIST)->SetWindowText(sText); 

				}



				*pth32ProcessID_out = th32ProcessID;

                

				// only for test !

				if ( bWithTraces )

				{

					// hold all modules (dlls usw.)

					hModSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID); 

					me32.dwSize = sizeof(MODULEENTRY32); 

					bGotModule = Module32First(hModSnap, &me32);

					while (bGotModule)

					{

						bGotModule = Module32Next(hModSnap, &me32);

					}



					// hold all threads

					hThrSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pe32.th32ProcessID); 

					thr32.dwSize = sizeof(THREADENTRY32); 

					bGotThread = Thread32First(hThrSnap, &thr32);

	//                bGotGuiThread = GetGUIThreadInfo(thr32.th32ThreadID, &guiThr);

                

					while (bGotThread)

					{

						bGotThread = Thread32Next(hThrSnap, &thr32);

					}

				}	//if ( bWithTraces )



				break;

			}

            else

            {

				// only for test !

				if ( bWithTraces )

				{

					sprintf(sBuf, "ProcessName = %s	\r\n  ", buf);

					//GetDlgItem(IDC_PROC_LIST_LIST)->GetWindowText(sEditText);

					strcpy(sText, sEditText);

					strcat(sText, sBuf);



					//GetDlgItem(IDC_PROC_LIST_LIST)->SetWindowText(sText);

				}



            }	