Finalizar um programa externo em execução

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

geraldenaw
Usuário Nível 1
Usuário Nível 1
Mensagens: 11
Registrado em: 12 Set 2005 11:27

Finalizar um programa externo em execução

Mensagem por geraldenaw »

Bom dia amigos,

Hj no nosso clipper temos o RUN ou ! para executar um programa externo, certo? O que eu queria era o contrário, um comando ou uma função que parasse um programa externo em execução, por exemplo, finalizar o programa Bematech Monitor. Se alguem puder me ajudar ficarei muito grato.
Desde já agradeço a todos pela atenção. Um abraço.
Geraldo Pereira França
Programador Clipper, Delphi e Java
Skype: gpfranca
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Finalizar um programa externo em execução

Mensagem por Pablo César »

Sei, o tópico é de vários anos atrás... rsrsrs se resolveu ou não eis a minha indicação:

Kill (matar) o processo de algum programa em execução pode chegar a ser inconveniente. Mas com a função -KILLAPPLICATION do WAPI do mestre Maligno pode resolver a questão.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Finalizar um programa externo em execução

Mensagem por asimoes »

Olá,
Tem esse exemplo do Vailton, com uma pequena adaptação, pode ajudar com o seu problema.
Caso haja interesse, você terá que compilar com harbour.
[]´s

Código: Selecionar todos

    * Routines to Kill a process, List all processes WITH user & domain names.
    * by Vailton Renato <vailtom@gmail.com> to Public Domain.
    *
    * UPDATED: 16/12/2009 - 12:15
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL NORMAN WALSH OR
    * ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    *
    procedure main()
       LOCAL cApp
       LOCAL i
       LOCAL n

       CLS

       ACCEPT 'Type process name to find (like CALC.EXE): ' TO cApp
       aProcs := {}

       if !empty( cApp ) .and. !( '.' $ cApp )
          cApp += '.exe'
       end

       n := WIN_GETPROCESSLIST( aProcs, cApp )

       ?
       ? 'WIN_GETPROCESSLIST( {}, "' + cApp + '" ) ->', n

       DO CASE
       CASE n == 0 ;  ?? ' - Success'
       CASE n == 1 ;  ?? ' - Argument error!'
       CASE n == 2 ;  ?? ' - Unable to obtain current process list!'
       CASE n == 3 ;  ?? ' - Error retrieving information about processes!'
       End

       aSort( aProcs ,,, {|x,y| x[1] < y[1] })

       ?
       ? 'Process Name          Process ID   ParentID   UserName (with Domain)'
       ? '====================  ==========   ========   ======================'
        * 123456789*123456789*  123456789*   12345678   123456789*123456789*

       For i := 1 TO Len( aProcs )
          ? PADR( aProcs[i,1], 21),;
            aProcs[i,2], ;
            aProcs[i,3], '  '

          IF Empty(aProcs[i,5]) .AND. Empty( aProcs[i,4] )
             *
          ELSE
            ?? '\\' + aProcs[i,5]+'\'+ aProcs[i,4]
          End
          inkey(0)
       End

       ? len(aProcs), ' process found!'
       ?

       IF Upper(cApp) == 'LETODB.EXE' .AND. !Empty( aProcs )

          p := Atail(aProcs)[ 2 ]

          IF Alert( 'You want to kill the process number ' + alltrim(str(p)) + '?',;
                {'No','Yes'} ) == 2
             ?
             ? 'Kill incmail.exe, PID:', p, " -->  "
             ?? WIN_KILLPROCESS( p )
             ?
          End
       End

       QUIT

    ************************
    #pragma BEGINDUMP
    #include <windows.h>
    #include <windef.h>
    #include <tlhelp32.h>
    #include <hbapi.h>
    #include <hbapiitm.h>

    static
    BOOL GetUserAndDomainFromPID( DWORD ProcessId, PHB_ITEM pUser, PHB_ITEM pDomain )
    {
      HANDLE hToken;
      HANDLE ProcessHandle;
      DWORD cbBuf;
      SID_NAME_USE snu;
      char *User = NULL;
      char *Domain = NULL;
      DWORD UserSize = 0L;
      DWORD DomainSize = 0L;
      BOOL bResult = FALSE;

      ProcessHandle = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, ProcessId );

      if (ProcessHandle)
      {
        if (OpenProcessToken(ProcessHandle, TOKEN_QUERY, &hToken))
        {
          BOOL bSuccess = FALSE;
          PTOKEN_USER ptiUser;
         
          if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &cbBuf ))
          {
             ptiUser  = (TOKEN_USER *) hb_xgrab( cbBuf );
             bSuccess = GetTokenInformation( hToken, TokenUser, (LPVOID) ptiUser, cbBuf, &cbBuf);
          }

          CloseHandle(hToken);

          if (bSuccess)
          {
             LookupAccountSid( NULL, ptiUser->User.Sid, NULL, &UserSize, NULL, &DomainSize, &snu);

             if (UserSize != 0 && DomainSize != 0)
             {
               User   = (char *) hb_xgrab( UserSize );
               Domain = (char *) hb_xgrab( DomainSize );

               if (LookupAccountSid( NULL, ptiUser->User.Sid, User, &UserSize,
                                      Domain, &DomainSize, &snu))
               {
                /* Result OK */
                bResult = TRUE;
               }
             }
           }

          if (ptiUser)
             hb_xfree( ptiUser );
        }
        CloseHandle(ProcessHandle);
      }

      if (!User)
          hb_itemPutC( pUser, "" );
      else
          hb_itemPutCLPtr( pUser, User, UserSize );

      if (!Domain)
          hb_itemPutC( pDomain, "" );
      else
          hb_itemPutCLPtr( pDomain, Domain, DomainSize );

      return bResult;
    }

    /*
    * WIN_GETPROCESSLIST( aArray [, <cProcessToFind> ] ) -> nResult
    * Get current process list on Windows OS. by Vailton Renato <vailtom@gmail.com>
    *
    * Returns:
    *
    *  0 - Success
    *  1 - Argument error
    *  2 - Unable to obtain current process list.
    *  3 - Error retrieving information about processes.
    *
    * 15/12/2009 - 18:58:58
    */
    HB_FUNC( WIN_GETPROCESSLIST )
    {
      HANDLE hProcessSnap;
      PROCESSENTRY32 pe32;
      PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY );
      const char * szAppName = hb_parcx(2);
      BOOL bCanAdd = TRUE;

       if( !pArray )
       {
          hb_retni( 1 );
          return;
       }

      // Take a snapshot of all processes in the system.
      hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

      if( hProcessSnap == INVALID_HANDLE_VALUE )
      {
        // CreateToolhelp32Snapshot (of processes)
        hb_retni( 2 );
        return;
      }

      // Set the size of the structure before using it.
      pe32.dwSize = sizeof( PROCESSENTRY32 );

      // Retrieve information about the first process,
      // and exit if unsuccessful
      if( !Process32First( hProcessSnap, &pe32 ) )
      {
        hb_retni( 3 );
        CloseHandle( hProcessSnap );          // clean the snapshot object
        return;
      }

      // Ignores a empty string on seconds argument
      if ( hb_parclen(2) < 1 )
          szAppName = NULL;

      // Now walk the snapshot of processes, and
      // display information about each process in turn
      do
      {
        PHB_ITEM pSubarray;

        if (szAppName)
          bCanAdd = ( hb_stricmp( szAppName, pe32.szExeFile ) == 0 );

        if (bCanAdd)
        {
           pSubarray = hb_itemNew( NULL );

           hb_arrayNew( pSubarray, 5 );
           hb_arraySetC    ( pSubarray, 1, pe32.szExeFile );                    // Process Name
           hb_arraySetNInt ( pSubarray, 2, pe32.th32ProcessID );                // Process ID
           hb_arraySetNInt ( pSubarray, 3, pe32.th32ParentProcessID );          // Parent process ID

           GetUserAndDomainFromPID( pe32.th32ProcessID,
                                    hb_arrayGetItemPtr( pSubarray, 4 ),         // User
                                    hb_arrayGetItemPtr( pSubarray, 5 ) );       // Domain
           hb_arrayAddForward( pArray, pSubarray );
        }
      } while( Process32Next( hProcessSnap, &pe32 ) );

      CloseHandle( hProcessSnap );
      hb_retni( 0 );
      return;
    }

    /*
    * WIN_KILLPROCESS( <nProessIDtoKill> ) -> lKilled
    * Kill a process using Win32 API. by Vailton Renato <vailtom@gmail.com>
    * 16/12/2009 - 00:08:48
    */
    HB_FUNC( WIN_KILLPROCESS )
    {
       DWORD ProcID;
       BOOL Result = FALSE;

       if (HB_ISNUM(1))
       {
          ProcID = (DWORD) hb_parnl(1);
          Result = TerminateProcess(OpenProcess( PROCESS_TERMINATE, FALSE, ProcID ),0);
       }

       hb_retl( Result );
    }

    #pragma ENDDUMP
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

Finalizar um programa externo em execução

Mensagem por Abel »

ola pessoal,
pela primeira vez to tendo a necessidade de fechar um programa aberto no windows para continuar a execucao do meu sistema.

Código: Selecionar todos

Function Process_Win32_Kill(cExecutavel)
Local oWmiService, oListaProcess, oProcessos
oWmiService=Service_WMI()
oListaProcess=oWmiService:ExecQuery("select * from Win32_Process where Name='"+cExecutavel+"'")
For Each oProcessos in oListaProcess
   oProcessos:Terminate()
Next
Return .T.

Function Service_WMI2()
Static oWmiService 
Local oScriptObj
If oWmiService==nil
   oScriptObj=CREATEOBJECT("wbemScripting.SwbemLocator")
   oWmiService=oScriptObj:ConnectServer()
End If
Return oWmiService
Utilizando estas duas funcoes acima, ele fecha normalmente
Exemplo:

Process_Win32_Kill("calc.exe")

ele ate fecha a calculadora corretamente, mas quando encerro meu sistema o windows apresenta uma mensagem assim:

O SISTEMA.exe encontrou um problema e precisa ser fechado.

Se voce estava no meio de alguma operacao, as informacoes nas quais voce estava tabalhando podem ter sido perdidas.

Informe este problema a Microsoft.
Criamos um relatorio de erros que voce pode nos enviar. Esse relatorio sera considerado confidencial e anonimo.
Para ver os dados contidos neste relatorio de erros. Clique aqui.

Alguem ja teve algo parecido ?

Agradeço desde ja a atencao,
ABEL
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Finalizar um programa externo em execução

Mensagem por fladimir »

Abel, comecei a passar por isso agora numa função q implementei e antes mando dar um Kill no processo caso exista e ok, roda normal, mas ao sair do sistema da o erro q vc mencionou...

Estou analisando se conseguir resolver eu posto aki.

[]´s
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Finalizar um programa externo em execução

Mensagem por fladimir »

Resolvi assim, peguei a função disponibilizada pelo Vailton aki no fórum q lista os processos e pergunta se quer Matar determinado processo e modifiquei criando uma função chamada KillProcess q abaixo compartilho o código.

Código: Selecionar todos

PROCEDURE KillProcess( cProcess )
	LOCAL aProcs := {}

   IF !EMPTY( cProcess ) .and. !( '.' $ cProcess )
      cProcess += '.exe'
   END

	WIN_GETPROCESSLIST( aProcs, cProcess ) //--> Aki carrega no array aProcs a lista de TODOS processos q estão sendo executados, caso cProcess fosse NIL, 
                                          //--> como eu passo como parametro o nome do processo q quero finalizar ele retorna somente relacionado a ele
   IF !EMPTY(aProcs) .AND. WIN_KILLPROCESS( aProcs[1][2] ) //--> Se tem tem o processo no array aProcs e se conseguir finalizar ele, retorna TRUE
   	inkey(0.3)
   	RETURN .T.
   ENDIF
RETURN .F.
Funções disponibilizadas pelo Vailton neste tópico de onde foi baseado a função aki disponibilizada.

Código: Selecionar todos

************************
#pragma BEGINDUMP
#include 
#include 
#include 
#include 
#include 

static
BOOL GetUserAndDomainFromPID( DWORD ProcessId, PHB_ITEM pUser, PHB_ITEM pDomain )
{
  HANDLE hToken;
  HANDLE ProcessHandle;
  DWORD cbBuf;
  SID_NAME_USE snu;
  char *User = NULL;
  char *Domain = NULL;
  DWORD UserSize = 0L;
  DWORD DomainSize = 0L;
  BOOL bResult = FALSE;

  ProcessHandle = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, ProcessId );

  if (ProcessHandle)
  {
    if (OpenProcessToken(ProcessHandle, TOKEN_QUERY, &hToken))
    {
      BOOL bSuccess = FALSE;
      PTOKEN_USER ptiUser;
      
      if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &cbBuf ))
      {
         ptiUser  = (TOKEN_USER *) hb_xgrab( cbBuf );
         bSuccess = GetTokenInformation( hToken, TokenUser, (LPVOID) ptiUser, cbBuf, &cbBuf);
      }

      CloseHandle(hToken);

      if (bSuccess)
      {
         LookupAccountSid( NULL, ptiUser->User.Sid, NULL, &UserSize, NULL, &DomainSize, &snu);

         if (UserSize != 0 && DomainSize != 0)
         {
           User   = (char *) hb_xgrab( UserSize );
           Domain = (char *) hb_xgrab( DomainSize );

           if (LookupAccountSid( NULL, ptiUser->User.Sid, User, &UserSize,
                                  Domain, &DomainSize, &snu))
           {
            /* Result OK */
            bResult = TRUE;
           }
         }
       }

      if (ptiUser)
         hb_xfree( ptiUser );
    }
    CloseHandle(ProcessHandle);
  }

  if (!User)
      hb_itemPutC( pUser, "" );
  else
      hb_itemPutCLPtr( pUser, User, UserSize );

  if (!Domain)
      hb_itemPutC( pDomain, "" );
  else
      hb_itemPutCLPtr( pDomain, Domain, DomainSize );

  return bResult;
}

/*
* WIN_GETPROCESSLIST( aArray [,  ] ) -> nResult
* Get current process list on Windows OS. by Vailton Renato 
*
* Returns:
*
*  0 - Success
*  1 - Argument error
*  2 - Unable to obtain current process list.
*  3 - Error retrieving information about processes.
*
* 15/12/2009 - 18:58:58
*/
HB_FUNC( WIN_GETPROCESSLIST )
{
  HANDLE hProcessSnap;
  PROCESSENTRY32 pe32;
  PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY );
  const char * szAppName = hb_parcx(2);
  BOOL bCanAdd = TRUE;

   if( !pArray )
   {
      hb_retni( 1 );
      return;
   }

  // Take a snapshot of all processes in the system.
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {
    // CreateToolhelp32Snapshot (of processes)
    hb_retni( 2 );
    return;
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )
  {
    hb_retni( 3 );
    CloseHandle( hProcessSnap );          // clean the snapshot object
    return;
  }

  // Ignores a empty string on seconds argument
  if ( hb_parclen(2) < 1 )
      szAppName = NULL;

  // Now walk the snapshot of processes, and
  // display information about each process in turn
  do
  {
    PHB_ITEM pSubarray;

    if (szAppName)
      bCanAdd = ( hb_stricmp( szAppName, pe32.szExeFile ) == 0 );

    if (bCanAdd)
    {
       pSubarray = hb_itemNew( NULL );

       hb_arrayNew( pSubarray, 5 );
       hb_arraySetC    ( pSubarray, 1, pe32.szExeFile );                    // Process Name
       hb_arraySetNInt ( pSubarray, 2, pe32.th32ProcessID );                // Process ID
       hb_arraySetNInt ( pSubarray, 3, pe32.th32ParentProcessID );          // Parent process ID

       GetUserAndDomainFromPID( pe32.th32ProcessID,
                                hb_arrayGetItemPtr( pSubarray, 4 ),         // User
                                hb_arrayGetItemPtr( pSubarray, 5 ) );       // Domain
       hb_arrayAddForward( pArray, pSubarray );
    }
  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  hb_retni( 0 );
  return;
}

/*
* WIN_KILLPROCESS(  ) -> lKilled
* Kill a process using Win32 API. by Vailton Renato 
* 16/12/2009 - 00:08:48
*/
HB_FUNC( WIN_KILLPROCESS )
{
   DWORD ProcID;
   BOOL Result = FALSE;

   if (ISNUM(1))
   {
      ProcID = (DWORD) hb_parnl(1);
      Result = TerminateProcess(OpenProcess( PROCESS_TERMINATE, FALSE, ProcID ),0);
   }

   hb_retl( Result );
}

#pragma ENDDUMP
Agora não testei se rodando em um server TS com mais de uma sessão aberta se o processo é finalizado em todas as sessões ou somente na q mandou executar a função.

Depois se conseguir testar isto compartilho, aki até lá se outro colega souber irá contribuir para esta informação.

[]´s
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Responder