9/23/2016

To run an external file to ShellExecute and kill processes. in MFC (and window active by PID or process handle)




Firstly, Check executing process to make by me.
And If process exist made by me, kill after check that saved PID is same.
"TerminateProcess" function used for kill process.
...
...
if (m_Manual_shell_hadle != NULL)
 {
  unsigned int tmp_pid = GetProcessId(m_Manual_shell_hadle); // retrieve PID
  //It comes under the pid value to the storage handle. Take on only kill pid is the same as the saved pid.
  if (tmp_pid == m_Manual_shell_pid)
  {
   TerminateProcess(m_Manual_shell_hadle, 1); //kill process
   m_Manual_shell_hadle = NULL;

   return 1; //sucess
  }
  
 }
 m_Manual_shell_hadle = NULL;
return 0; //not found
...
...


And, execute external file.

..
...
 SHELLEXECUTEINFO ShExecInfo = { 0 };
 ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
 ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
 ShExecInfo.hwnd = this->m_hWnd;
 ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = TargetPath; //external file name
 ShExecInfo.lpParameters = NULL; //aguments
 ShExecInfo.lpDirectory = NULL;
 ShExecInfo.nShow = SW_SHOW;
 ShExecInfo.hInstApp = NULL;

ShellExecuteEx(&ShExecInfo); //execute 

  //save pid and handle
  m_Manual_shell_pid = GetProcessId(ShExecInfo.hProcess); // retrieve PID
  m_Manual_shell_hadle = ShExecInfo.hProcess;

...
...


"m_Manual_shell_pid, m_Manual_shell_hadle" is our member variable.


and one more thing, if we want to window activating or taking to top on screen, using hwnd, to use below function.
///
::BringWindowToTop(hwnd);
 ::SetActiveWindow(hwnd);
 ::SetForegroundWindow(hwnd);
 ::ShowWindow(hwnd, SW_SHOWNORMAL);
 ::UpdateWindow(hwnd);
///

But to use these functions, we have to know hwnd value to active window.
We just know HANDLE value, then we can get Process id, that PID using GetProcessId and then
we can know hwnd using by this pid.

this is little complex, we should use callback function this -> EnumWindows(...)
The usage is like that,

firstly, make own function -> EnumWindowsProcMy
And call EnumWindows and then get hwnd.
see example code

HWND g_HWND = NULL;
BOOL CALLBACK EnumWindowsProcMy(HWND hwnd, LPARAM lParam)
{
 DWORD lpdwProcessId;
 GetWindowThreadProcessId(hwnd, &lpdwProcessId);
 if (lpdwProcessId == lParam)
 {
  g_HWND = hwnd;
  return FALSE;
 }
 return TRUE;
}


int CSomeClass::ActiveManualWindowIfAlive()
{

        if (m_Manual_shell_hadle != NULL)
 {
  unsigned int tmp_pid = GetProcessId(m_Manual_shell_hadle); // retrieve PID
  if (tmp_pid == m_Manual_shell_pid)
  {
   g_HWND = NULL;
   EnumWindows(EnumWindowsProcMy, m_Manual_shell_pid);
   if (g_HWND != NULL)
   {
    ::BringWindowToTop(g_HWND);
    return 1;
   }

  }
  
 }

 return 0;

}



Thank you.

No comments:

Post a Comment