Ajuda - Busca - Membros - Calendário
Versão Completa: Aplicação Pai vs Aplicação filha
Fórum Script Brasil > Programação & Desenvolvimento > Delphi, Kylix
darth_ivan
Caros,

tenho uma aplicação pai e uma filha desta. Quando a aplicação pai é fechada via gerenciador de tarefas, a aplicação filha continua rodando. Como faço para que isso não ocorra???
Denis Courcy
QUOTE(darth_ivan @ 23/01/2008 - 15:23) *
Caros,
tenho uma aplicação pai e uma filha desta. Quando a aplicação pai é fechada via gerenciador de tarefas, a aplicação filha continua rodando. Como faço para que isso não ocorra???

Pelo que entendi, você está rodando dois executáveis distintos, um chamado pelo outro. Quando acionamos um executável no DOS (Vou mencionar DOS mesmo que seja WINDOWS rodando, pois o Kernel básico trabalha com o mesmo princípio) este aloca um HANDLE (um ponteiro que indicará qual é a primeira posição do executável na RAM) independente de quem está chamando, fazendo com que cada aplicação rodando seja independente, mesmo se for chamada de outra aplicação. Este é o motivo pelo qual acontece o que você comentou acima.
Você pode enviar uma ordem de KILL no processo da aplicação filha. Mas você terá que guardar, em uma variável, o HANDLE de execução desta aplicação. Não conheço o delphi o suficiente para orientá-lo como fazer, infelizmente.
Jhonas
QUOTE
Você pode enviar uma ordem de KILL no processo da aplicação filha


voce pode usar esta função para fazer isto, onde ExeFileName é o nome da aplicação filha

CODE
uses
  Tlhelp32;

function KillTask(ExeFileName: string): Integer;
const
  PROCESS_TERMINATE = $0001;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  Result := 0;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
      Result := Integer(TerminateProcess(
                        OpenProcess(PROCESS_TERMINATE,
                                    BOOL(0),
                                    FProcessEntry32.th32ProcessID),
                                    0));
     ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;


abraço
Micheus
Apenas para completar o post do Jhonas, segue este outro post, visto que há diferenças em matar um processo em outras versões do Windows.

Mas o que vejo como problema é que qualquer dos processos que seja "morto" via gerenciador de tarefas (End Task ou Finalizar Processo) não recebe qualquer evento que informe isso (tipo um WM_QUIT ou WM_CLOSE). Assim, como matar a outra tarefa se a "vítima" nem sabe que vai ser "assassinada"?!

Penso que teria que ser utilizada alguma outra abordagem.

Abraços
Micheus
QUOTE(darth_ivan @ 23/01/2008 - 14:23) *
tenho uma aplicação pai e uma filha desta. Quando a aplicação pai é fechada via gerenciador de tarefas, a aplicação filha continua rodando. Como faço para que isso não ocorra???
darth_ivan, me ocorreu o seguinte, nas características de uso destas suas aplicações, você poderia por acaso ter a aplicação filha em uma DLL? Como vão operar estas suas aplicações?

Abraços
darth_ivan
Não, não estou usando nenhuma dll. Esses dois processos são apenas duas janelas, uma pai que chama outras janelas filhas. Consigo tratar com eventos e mensagens quando a janela pai e fechada normalmente, mas quando ela é fechada via gerenciador de tarefas, o processo pai é terminado mas os outros continuam rodando, e como tem um mutex para cada processo filho, quando o pai é assassinado, os filhos tem que ser assassinados também pois caso contrário, o usuário não consiguirá utilizar o software. Tem alguma forma de linkar o processo pai ao filho de forma que quando ele for assassinado, o filho também seja.

A sugestão do Jhonas, se não me engano, somente irá funcionar se eu utilizá-la no evento OnClose, mas isso não irá solucionar meu problema.
Micheus
QUOTE(darth_ivan @ 29/01/2008 - 14:24) *
Não, não estou usando nenhuma dll.
Não foi isto que eu perguntei. huh.gif
Eu perguntei se este processo filho poderia ser uma DLL ao invés de outra aplicação (.exe)

QUOTE
Esses dois processos são apenas duas janelas, uma pai que chama outras janelas filhas. Consigo tratar com eventos e mensagens quando a janela pai e fechada normalmente, mas quando ela é fechada via gerenciador de tarefas, o processo pai é terminado mas os outros continuam rodando, e como tem um mutex para cada processo filho, quando o pai é assassinado, os filhos tem que ser assassinados também pois caso contrário, o usuário não consiguirá utilizar o software. Tem alguma forma de linkar o processo pai ao filho de forma que quando ele for assassinado, o filho também seja.

A sugestão do Jhonas, se não me engano, somente irá funcionar se eu utilizá-la no evento OnClose, mas isso não irá solucionar meu problema.
É como eu disse, não há qualquer notificação (envio de mensagem) quando o encerramento é feito via gerenciador de tarefa. A aplicação simplesmente é removida da memória.

Mas, se você utilizar o segundo processo em uma DLL, e carregá-la em sua aplicação, ela será removida da memória juntamente com sua aplicação. Ou seja, as duas "morrem".

Abraços
darth_ivan
Mas tem como utilizar uma janela em uma dll? O processo filho é apenas um executável que estou chamando do processo pai, se tiver jeito de chamá-lo de um dll é até melhor pois o processo filho necessariamente vai ter que ser chamado via processo pai.

Uma outra solução seria matar o processo quando a janela fosse destruída, tem como fazer isso?
Micheus
QUOTE(darth_ivan @ 30/01/2008 - 09:23) *
Mas tem como utilizar uma janela em uma dll? O processo filho é apenas um executável que estou chamando do processo pai, se tiver jeito de chamá-lo de um dll é até melhor pois o processo filho necessariamente vai ter que ser chamado via processo pai.

Uma outra solução seria matar o processo quando a janela fosse destruída, tem como fazer isso?
Veja este exemplo, que é um esqueleto apenas didático para observar como as coisas ocorrem.

Os executáveis estão anexos, então teste eles e confira o código depois. Na aplicação Pai:
1) Há dois botões para carregar/"descarregar" uma aplicação filha tipo EXE. Observe que mesmo que você clique no X da aplicação pai, nós estaremos fechando a filha via evento OnClose. Se você matar a aplicação pai via gerenciador de tarefas, a aplicação filha fica rodando;
2) Há dois botões para carregar/"descarregar" uma aplicação filha tipo DLL. Observe, agora, que clicando no X da aplicação pai, o sistema descarregará a dll filha, mas de forma normal, gerando qualquer evento que a DLL possa processar. Se você matar a aplicação pai via gerenciador de tarefas, a DLL filha é descarregada, mas não será gerado qualquer evento;

Abraços

darth_ivan
Cara, muito obrigado pela sua ajuda, vou tentar convencer o pessoal que trabalha comigo a colocar os outros processos em dll.

Mas só uma última dúvida, se eu modularizar muito o sistema em dlls, chega a comprometer a performance???
Micheus
QUOTE(darth_ivan @ 31/01/2008 - 08:16) *
Mas só uma última dúvida, se eu modularizar muito o sistema em dlls, chega a comprometer a performance???
Que eu saiba não. Espero que mais alguém se manifeste a respeito.

Mas já que parece ser algo mais complexo do que eu imaginava (envolve desmembrar vários processos), acho que seria interessante você avaliar este artigo: E se fosse modularizado? (ref. ActiveDelphi)
Trata da modularização utilizando não DLLs, mas BPLs (que é basicamente uma DLL, mas com características introduzidas pela Borland). Eu acredito que as BPLs também sejam removidas da memória junto com a aplicação principal - é questão de testar. wink.gif

Mas modularizar o projeto é algo que traz algumas vantagens. O Exe fica mais enxuto, a manutenção por vezes mais simples, a atualização pode ser feita apenas no módulo alterado (não todo o programa), pode ser carregados apenas os módulos em uso. E por aí vai...
Procurei e achei mais estas outras citadas neste artigo: http://pjtsalina.codigolivre.org.br/pr/clu...hi/package.html

Abraços
Esta é uma versão simplificada de nosso conteúdo principal. Para ver a versão completa com maiores informações, formatação e imagens, por favor clique aqui.
Invision Power Board © 2001-2012 Invision Power Services, Inc.