Fechar um processo windows - com4j x java

9 respostas
M

Pessoal,

Tenho uma api utilizada para a geração de documentos office. Foi utilizado um projeto open source como base para nossa solução.

Usamos esta aplicação para gerar centenas de documentos por dia … são relatórios simples Word, planilhas e até diagramas Visio.

O problema que estou tendo é que em determinado momento, uma instancia do aplicativo trava na geração de um documento. Não gera o documento atual e trava toda minha fila.

Eu desenvolvi uma lógica para encerrar o processo travado, porém estou com dificuldades para identificar o processo travado.

Usando a própria biblioteca do com4j eu consigo listar todos os processos que estão atualmente rodando, porém não consigo identificar qual é o travado.

Eu tentei também mudando o titulo da janela da aplicação, porém, não consigo na lista de processos, trazer a informação do titulo da janela.

Alguém por acaso tem alguma dica de como contornar este problema?

Abraço,

9 Respostas

M

Fechar programa [RESOLVIDO]

M

Obrigado pela resposta, porém eu já havia pesquisado no fórum as possíveis respostas.

Fechar o processo não é o problema. O problema é identificar o processo que deve ser fechado.

Se você pensar que minha aplicação esta gerando centenas de arquivos simultaneamente, existem vários processos do winword.exe rodando e um deles travado. Eu precisaria de alguma forma identificar o processo travado e fechá-lo.

Eu tentei criando todos os processos com um titulo randômico para que assim eu consiga identificá-lo, porém, não consigo carregar a lista de processos trazendo o titulo da janela. Acho que nem vai ser possível desta forma, uma vez que nem todos os processos tem janela.

M

Não sei se ajuda, mas de qualquer forma segue:

public static boolean kill(String processo) {  
            try {  
                String line;  
                Process p = Runtime.getRuntime().exec("tasklist.exe /fo csv /nh");  
                BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));  
                while ((line = input.readLine()) != null) {  
                    if (!line.trim().equals("")) {  
                        if (line.substring(1, line.indexOf("\"", 1)).equalsIgnoreCase(processo)) {  
                            Runtime.getRuntime().exec("taskkill /F /IM " + line.substring(1, line.indexOf("\"", 1)));  
                            return true;  
                        }  
                    }  
                }  
                input.close();  
            } catch (Exception err) {  
                err.printStackTrace();  
            }  
            return false;  
        }

Esse código está aqui :

Como matar um processo no windows em Java

Acredito que isso seja o caminho, espero ter ajudado, sempre usei dessas formas.

M

Como eu disse no post acima, o problema não é matar o processo e sim identificar qual o processo correto deve ser finalizado.

[]'s

M

Novamente tentando ajudar, aqui listo todos os processos:

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  

public class ListProcess {  
    public static void main(String[] args) throws IOException {  

        Runtime runtime = Runtime.getRuntime();  

        String cmds[] = {"cmd", "/c", "tasklist"};  

        Process proc = runtime.exec(cmds);  

        InputStream inputstream = proc.getInputStream();  

        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);  

        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);  

        String line;  

        while ((line = bufferedreader.readLine()) != null) {  

            System.out.println(line);  

        }  

    }  

}

Tenho os processos, me parece que você tem uma String, “quase” o nome do processo, busco na lista por semelhança ou de qualquer outra forma, dai passo ela no meu código, a String correta:

import java.io.BufferedReader;
import java.io.InputStreamReader;


public class KillAll {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String process = "firefox.exe";
        
        kill(process);

    }
    
    
    public static boolean kill(String processo) {    
        try {    
            String line;    
            Process p = Runtime.getRuntime().exec("tasklist.exe /fo csv /nh");    
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));    
            while ((line = input.readLine()) != null) {    
                if (!line.trim().equals("")) {    
                    if (line.substring(1, line.indexOf("\"", 1)).equalsIgnoreCase(processo)) {    
                        Runtime.getRuntime().exec("taskkill /F /IM " + line.substring(1, line.indexOf("\"", 1)));    
                        return true;    
                    }    
                }    
            }    
            input.close();    
        } catch (Exception err) {    
            err.printStackTrace();    
        }    
        return false;    
    }    

}

Bem é maneira que eu faria, espero novamente ter ajudado :slight_smile:

Se possível :smiley:

M

Não consigo fazer isso porque quando estou com a aplicação rodando, existem centenas de processos winword.exe … um para cada documento que esta em processo de geração.

O problema seria finalizar somente o que esta com problemas. Eu precisaria de alguma forma identificar cada processo e na hora que eu verificasse que o mesmo estivesse travado, tendo sua identificação, eu conseguiria finalizá-lo.

Se eu finalizar como você sugeriu, finalizaria toda a minha geração de documentos, quando na verdade, eu gostaria de finalizar somente um processo que estaria com problemas.

Sua solução seria eficaz se houvesse como alterar o nome do processo.

Tipo, para cada processo que crio, colocaria um nome randômico e caso trave, teria somente que passar este nome para uma função parecida com essa que você fez.

De qq forma, obrigado pela sugestão

M

Command-line tool for finding out who is locking a file

Handle v3.5

Não sei se ajudaria, de qualquer forma segue.

J

Não tem como identificar os processos pelo PID?

M

Quando eu crio o processo usando o COM4J, não tenho como recuperar o PID. Então, depois de criado, não consigo mais vincular um trabalho que esta em andamento com um processo que esta rodando.

Eu recupero uma lista com todos os processos dos objetos office, porém, como estou gerando centenas de documentos não consigo garantir que tal processo esta associado a tal execução.

Pense no seguinte:

Tenho um pool de Trabalhos ( entenda como geração de documento ). Cada requisição que eu recebo, eu disparo um trabalho do pool e ele então cria uma instancia do objeto Com4J para processar a geração do documento. O problema é que não encontrei ainda nenhuma forma de conseguir associar o trabalho que esta em andamento ao processo windows criado para esta execução.

Eu consigo saber qual o trabalho esta travado, porém, não consigo saber qual o processo do windows é o responsável pelo processamento deste trabalho.

Criado 30 de outubro de 2012
Ultima resposta 31 de out. de 2012
Respostas 9
Participantes 3