Clipper On Line • Ver Tópico - Verificar aplicativo/processo está rodando na memória
Página 1 de 2

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 26 Jan 2017 18:30
por NiltonGM
Pessoal,

Exite alguma função do Harbour para verificar se um aplicativo ou processo está rodando na memória?, Hoje eu consigo saber se o meu próprio executável já está rodando para não abrir outra estância usando o velho truque de criar um arquivo txt e travar ele deixando-o aberto enquanto rodo o aplicativo, uma outra estância do mesmo aplicativo tenta deletar este arquivo se exitir, se não conseguir sabemos que uma estância deste aplicativo já está rodando, mas e quando queremos saber de um terceiro aplicativo se está rodando? Como ler (pegar) do Windows a lista de processos ativos?

Velho truque:
          if File('cte_emuso.01')
             fErase('cte_emuso.01')
             if fError() <> 0
                MessageBoxTimeout('O programa já se encontra em uso!', 'PrintCTe TMS Expresso.Cloud ' + g_cVersao + ': Aviso!', MB_ICONEXCLAMATION, 7000 )
                QUIT
             end
             RegistraLog('Sistema foi interrompido anteriormente')
          end

          p_SOSHandle := fCreate('cte_emuso.01') // Cria o arquivo de controle
          fClose(p_SOSHandle)
          p_SOSHandle := fOpen('cte_emuso.01',1) // Abre travando o arquivo de controle

          RegistraLog('Sistema iniciado (em execução)' )


Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 26 Jan 2017 20:41
por Claudio Soto
Para impedir que el mismo programa se ejecute dos veces usar:

SET MULTIPLE ON | OFF [ WARNING ]      
 
Impedes Attempts To Run Multiple Instances Of The Application

Para averiguar cuáles son los procesos en ejecución ver:

- GetCurrentProcessID() --> return nProcessID
 
- EnumProcessID () ---> return array { nProcessID1, nProcessID2, ... }
 
- GetWindowThreadProcessID ( hWnd, @nThread, @nProcessID )
     
- IsWow64Process ( [ nProcessID ] ) --> return lBoolean
- return TRUE  if a 32-bit application is running under 64-bit Windows (WOW64)
- return FALSE if a 32-bit application is running under 32-bit Windows
- return FALSE if a 64-bit application is running under 64-bit Windows
Note: WOW64 (Win32 On Win64) is the x86 emulator that allows 32-bit Windows-based applications to running on 64-bit Windows
 
- GetProcessName ( [ nProcessID ] ) --> return cProcessName
 
- GetProcessFullName ( [ nProcessID ] ) --> return cProcessFullName
 
- GetProcessImageFileName ( [ nProcessID ] ) --> return cProcessImageFileName
 
- TerminateProcess ( [ nProcessID ] , [ nExitCode ] )
   

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 26 Jan 2017 22:24
por JoséQuintas
Valeu, resolveu meu problema.

Comentário sobre a forma como a minigui trata as traduções:
atrapalha resolver certos problemas.

Gastei horas tentando resolver um problema e este post resolveu.

Eu teria resolvido muito antes, caso eu pudesse ter pesquisado a string "Already Running" nos fontes.

Como estão em um array:
      _HMG_MESSAGE [1] := 'Are you sure ?'
      _HMG_MESSAGE [2] := 'Close Window'
      _HMG_MESSAGE [3] := 'Close not allowed'
      _HMG_MESSAGE [4] := 'Program Already Running'
      _HMG_MESSAGE [5] := 'Edit'
      _HMG_MESSAGE [6] := 'Ok'
      _HMG_MESSAGE [7] := 'Cancel'
      _HMG_MESSAGE [8] := 'Apply'
      _HMG_MESSAGE [9] := 'Pag.'


Fica quase impossível de localizar a rotina aonde está essa mensagem.

Nota: Aqui sempre retorna que o programa está rodando, Harbour 3.4, mingw 32 bits, Windows 10 64 bits

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 27 Jan 2017 16:31
por NiltonGM
Claudio Soto ou Zeh, ao usar a função EnumProcessID(), dá erro: "undefined reference to 'ENUMPROCESSID; Não tem uma função tipo GetProcessID( 'PrintCte') que busca o processo pelo nome? Aí sim retornaria um ID ou 0/NIL pra eu saber q não está em execução.
A função que mais se aproxima do que eu preciso é a GetProcessName([id]), porem só é util quando já sabemos de antemão o id do processo, só que esse id altera a cada vez que o aplicativo é executado.
Quanto ao comando SET MULTIPLE ON/OFF, muito show!, Sabem me dizer se o executável com essa linha "SET MULTIPLE OFF" estiver em um Servidor e for invocado por uma estação, ele impede outra instância apenas na estação que invocou mas não em outra, ou só permite a execução um uma estação por vez?

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 27 Jan 2017 17:26
por JoséQuintas
A rotina precisa do Windows pra testar se está rodando.
Então é vinculado a uma estação/um Windows.

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 27 Jan 2017 19:49
por Claudio Soto
Nilton, todas las funciones que mencioné hacen parte de HMG.3.4.3

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 28 Jan 2017 13:56
por NiltonGM
Oi Claudio Soto,

Claudio Soto escreveu:Nilton, todas las funciones que mencioné hacen parte de HMG.3.4.3


Utilizo HMG 3.4.3 Stable (32bits), veja na imagem anexa o erro que a função não existe. Será que a Sintax da função está errada?

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 28 Jan 2017 23:04
por Claudio Soto
El nombre esta mal, la funcion esta definida como
EnumProcessesID()

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 29 Jan 2017 10:50
por NiltonGM
Valeu Claudio Soto,

Funcionou! Agora sim consigo montar uma função que verifica se o processo está ativo ou não pelo Nome buscando no array retornado pela função EnumProcessesID(), só para constar, percebi que os processos do Windows que estão suspensos retornam o nome vazio pela função GetProcessName(nID), sendo o nID retornado no Array pela função EnumProcessesID().
:-Y

Obrigado

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 29 Jan 2017 11:21
por rubens
Nilton talvez te ajude a implementar a função...
não conhecia as funções deste post.

*******************************************************************************   
function EstaRodandoKillExe( _cExe, _nKill )
/*
* Verificar se um Exe est  sendo executado e podendo at‚ derrub -lo
* Parametros: _cExe, _nKill
* Retorno: Retorno - .t. se estiver rodando
*
* Autor: toya
*/
local Retorno := .f.
local oScriptObj
local oWmiService
local oListaProcess
local oProcessos

HB_DEFAULT(@_nKill,0)

oScriptObj := CREATEOBJECT( "wbemScripting.SwbemLocator" )
oWmiService := oScriptObj:ConnectServer()
oListaProcess := oWmiService:ExecQuery( "select * from Win32_Process where Name='" + _cExe + "'" )

for Each oProcessos in oListaProcess
   Retorno := .t.
   if _nKill == 2
      oProcessos:Terminate() // mata o _cEXE
   endif
next

return Retorno

*******************************************************************************   
function FechaPrograma( _cExe )
/*
*/
local Retorno := .f.
local oScriptObj
local oWmiService
local oListaProcess
local oProcessos

oScriptObj := CREATEOBJECT( "wbemScripting.SwbemLocator" )
oWmiService := oScriptObj:ConnectServer()
oListaProcess := oWmiService:ExecQuery( "select * from Win32_Process where Name='" + _cExe + "'" )

for Each oProcessos in oListaProcess
   Retorno := .t.
   oProcessos:Terminate() // mata o _cEXE
next

return Retorno


Rubes

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 30 Jan 2017 17:02
por NiltonGM
Rubens,

Testei sua função também, funciona que é uma beleza, mesmo sem entender essa classe 'wbemScripting.SwbemLocator', muito louca! Ela tem um metodo 'ExecQuery()', que que é isso companheiro?!! rs

Abraços

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 31 Jan 2017 08:12
por rubens
Bom dia...

Nilton...

Então... na época que precisei disso aí estava tendo problemas com o ACBR que simplesmente congelava... daí fui pesquisando e testando e cheguei a essa função aí... Também não sei muito bem o que e como funciona, mas para mim o importante é que funcionou !!! Não força muito não que o lado de cá espana ... kkkk

Uma coisa que percebi que as vezes a gente fica ligado que comando sql servem somente para banco de dados mas não é o que parece né. Já vi alguns exemplos trabalhando em listas, filas... Este aí é um né... recuperou a lista de programas executados e gerou uma query nele... pelo menos foi o que "deduzi"...

Para mim este é um conceito errado do harbour... Quando estamos migrando vemos o seguinte: 'HArbour é a mesma coisa do clipper', na realidade o harbour é compatível com o clipper né, digamos que aproveita o clipper, mas é um mundo totalmente novo e com um aprendizado duro e longo pela frente... Nom meu pouco conhecimento, até agora não vi nada que não se consiga fazer com o harbour, mais difícil, mas possível...

Rubens

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 01 Fev 2017 15:18
por Pablo César
Aqui tem outro tipo de exemplo feito pelo colega Dave que procura pelo título da janela:

Imagem

http://www.hmgforum.com/viewtopic.php?p=49053#p49053

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 04 Abr 2018 09:30
por porter
Olá pessoal,
Estou reabrindo esse tópico para tirar uma dúvida com relação
a rotina acima postada pelo Rubens, com relação aos parâmetros:
_cExe, seria o nome do executavel do sistema ?
e _nKill o que tem que ser informado nesse parâmetro ?

function EstaRodandoKillExe( _cExe, _nKill )

HARBOUR 3.2.0(dev)

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 04 Abr 2018 14:14
por rubens
Poter...

Foi uma função tirada de outra função... não sei para que serve o nKill e nem tentei executar sem ele para ver se realmente precisa... já o o _cExe é sim o nome do programa que você quer ver se está rodando... pelo que testei tem que ser exatamente o nome do executável, no meu caso uso para ver se o acbrmonitor está em execução daí se o executável do seu aplicativo é AcbrMonitor.exe e colocar acbrmonitor.exe não vai funcionar..

Rubens

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 04 Abr 2018 17:10
por porter
Olá Rubens,
Então vou tentar executar essa rotina sem o nKill para ver se dá certo,
Obrigado.

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 22 Mar 2021 15:10
por carlaoonline
Boa tarde a todos !

Esse tópico é antigo e essa solução apresentada por mim também é mas sempre me serviu.

Ela verifica se o programa (executável) já está rodando .

No meu caso não usei passagem de nome de arquivo como parâmetro na função pois é para verificar sempre os os mesmos nomes: "A_MENU1.EXE" ou o conteúdo da variável "NOME_CLIENTE", mas é possível implementa-la da forma que quiser.

Ela consiste em rodar o tasklist.exe>arq_log.txt e depois lê esse arquivo.

Uso no windows 10 em março de 2021 e ainda funciona bem.

Primeiro a chamada para a função:
//-----------------------------------------------------------------------------
// Aqui verifica o numero de vezes que esta aberto esse executavel e coloca um numero de referencia nele....
//-----------------------------------------------------------------------------
PUBLIC NOME_CLIENTE:="DINAMICA"
TEMPORARIO="ZYX_"

   NUMERO_DO_APP=VER_NUM_TELAS()
   IF NUMERO_DO_APP>3
      ALERT("N" + CHR( 163 ) + "mero de aberturas excedido.;Existem 3 telas abertas do sistema!")
      close all
      quit
   ENDIF
//-----------------------------------------------------------------------------


Agora a função:

//
// Esta funcao varre o tasklist para ver se o programa ja esta rodando 
// Nesse caso o A_MENU1.EXE ou o contido variavel NOME_CLIENTE
//
FUNCTION VER_NUM_TELAS()
  local AA,BB,CC,DD,UM

   //--- Se existir um arquivo de LOG anterior, entao apaga ele
   AA=TEMPORARIO+"LOG.TXT"
   IF FILE(AA)  // NAO USAR LETO_FILE, eh para verificacao local
      ERASE &AA
   ENDIF
   
   //--- Monta a query
   AA="TASKLIST>"+TEMPORARIO+"LOG.TXT"
   
   //--- Executa a query
   //--- Colocando dentro do arquivo TXT de log a relacao de todos arquivos rodando no PC
   HB_RUN (AA)
   AA=TEMPORARIO+"LOG.TXT"
   UM=MEMOREAD(AA)
   CC=NOME_CLIENTE+".EXE"
   DD=0
   
   //--- AQUI verifica se ha outro programas abertos no computador local ------
   FOR F=1 TO MLCOUNT(UM,100)  // Quantidade de linhas (memoline) em UM ate 100 colunas.
       BB=MEMOLINE(UM,100,F)  // Atribui a BB ate 100 caracteres da linha F  do arquivo de LOG gerado
       IF "A_MENU1.EXE"$UPPER(BB) .OR. CC$UPPER(BB) // Verifica de nessa linha tem um dos arquivos mencionado
          DD++  // Se houver entao incrementa a variavel DD
          *ALERT("ENCONTRADA "+STR(DD)+" OCORRENCIA")
       ENDIF
   NEXT
   
   //--- Apaga o arquivo de LOG gerado.
   AA=TEMPORARIO+"LOG.TXT"
   IF FILE(AA)  // NAO USAR LETO_FILE, eh para verificacao local
      ERASE &AA
   ENDIF
   RETURN DD


Aqui a mesma função porém enxuta utilizando o comando Hb_ProcessRun:

//
// Esta funcao varre o tasklist para ver se o programa ja esta rodando 
// Nesse caso o A_MENU1.EXE ou o contido variavel NOME_CLIENTE
//
FUNCTION VER_NUM_TELAS()
local AA, BB, CC:=NOME_CLIENTE+".EXE" , DD:=0 , UM:=""

//--- Aqui coloca o resultado do comando TASKLIST dos DOS na variavel UM
// nResult := hb_ProcessRun( cCommand, [cStdIn], [@cStdOut], [@cStdErr], [lDetach] )
AA= hb_processRun( "tasklist" ,, @UM,, .t. )
   
//--- AQUI verifica se ha outro programas abertos no computador local ------
FOR F=1 TO MLCOUNT(UM,100)  // Quantidade de linhas (memoline) em UM ate 100 colunas.
    BB=MEMOLINE(UM,100,F)  // Atribui a BB ate 100 caracteres da linha F  do arquivo de LOG gerado
    IF "A_MENU1.EXE"$UPPER(BB) .OR. CC$UPPER(BB) // Verifica de nessa linha tem um dos arquivos mencionado
        DD++  // Se houver entao incrementa a variavel DD
        *ALERT("ENCONTRADA "+STR(DD)+" OCORRENCIA")
    ENDIF
NEXT

RETURN DD

Verificar aplicativo/processo está rodando na memória

MensagemEnviado: 31 Jul 2021 15:14
por JAIR RANGEL
Boa tarde, Amigos

Mesmo o post sendo antigo, me senti na obrigação de passar aqui hoje para dizer que a rotina apresentada pelo Rubens funciona maravilhosamente bem...
É certo que não tentei decifrar todas as linhas da função, pois tem coisas ali que entortou a mente, mas funciona.

Abraço a todos e vamos em frente!