【问题标题】:How to stop process started with an Eclipse external tools configuration如何停止使用 Eclipse 外部工具配置启动的进程
【发布时间】:2016-03-04 18:58:21
【问题描述】:

我有一个启动 java 程序的 Windows .bat 文件。为方便起见,我创建了一个 Eclipse external tools configuration 以直接从 IDE 启动它并从 Eclipse 控制台读取其标准输出。

但是,当我在控制台视图中使用终止按钮(红色方块)从 Eclipse 终止进程时,程序仍在运行。

如何从 Eclipse 中终止它(无需创建单独的启动配置来搜索并以编程方式终止它)?

【问题讨论】:

  • 请编辑您的问题并发布启动此 java 程序的批处理文件的源代码!
  • @Hackoo 我可以用一个简单的批处理文件复制它,内容为:java -jar MyApp.jar,应用程序只是显示一个空窗口 (JFrame)。在我从 Eclipse 控制台终止进程后,该窗口仍然可见。我的实际应用有点复杂,但问题是一样的。
  • 那么您的应用程序创建的这个进程的名称是什么?
  • 我认为这里的问题是你只杀死了.bat 进程,而不是它的子进程。这可能会对您有所帮助:Kill batch file in such a way that its children are killed too, in Windows.
  • @DraganBozanovic 如果你想杀死所有 java.exe 进程:taskkill /F /IM java.exe /Twmic process where "name like '%java%'" delete

标签: java eclipse batch-file


【解决方案1】:

你应该使用这个命令TASKKILL

语法 TASKKILL [/S 系统 [/U 用户名 [/P [密码]]]] { [/FI 过滤器] [/PID 进程 ID | /IM 图像名] } [/F] [/T]

选项 /S system 要连接的远程系统。

/U   [domain\]user    The user context under which
                      the command should execute.

/P   [password]       The password. Prompts for input if omitted.

/F                    Forcefully terminate the process(es).

/FI  filter           Display a set of tasks that match a
                      given criteria specified by the filter.

/PID process id       The PID of the process to be terminated.

/IM  image name       The image name of the process to be terminated.
                      Wildcard '*' can be used to specify all image names.

/T                     Tree kill: terminates the specified process
                       and any child processes which were started by it.

过滤器应用以下过滤器之一:

         Imagename   eq, ne                  String
         PID         eq, ne, gt, lt, ge, le  Positive integer.
         Session     eq, ne, gt, lt, ge, le  Any valid session number.
         Status      eq, ne                  RUNNING | NOT RESPONDING
         CPUTime     eq, ne, gt, lt, ge, le  Time hh:mm:ss
         MemUsage    eq, ne, gt, lt, ge, le  Any valid integer.
         Username    eq, ne                  User name ([Domain\]User).
         Services    eq, ne                  String The service name
         Windowtitle eq, ne                  String
         Modules     eq, ne                  String The DLL name

例子:

TASKKILL /S system /F /IM notepad.exe /T
TASKKILL /PID 1230 /PID 1241 /PID 1253 /T
TASKKILL /F /IM notepad.exe /IM mspaint.exe
TASKKILL /F /FI "PID ge 1000" /FI "WINDOWTITLE ne untitle*"
TASKKILL /F /FI "USERNAME eq NT AUTHORITY\SYSTEM" /IM notepad.exe
TASKKILL /S system /U domain\username /FI "USERNAME ne NT*" /IM *
TASKKILL /S system /U username /P password /FI "IMAGENAME eq note*"

这是一个名为:ProcessKiller.bat的示例:

一次性杀死 eclipse.exejavaw.exe 等不同进程并将结果记录到日志文件中以判断成功或失败!

@echo off
cls & color 0A
Mode con cols=50 lines=6
Title ProcessKiller by Hackoo 2016
set process="eclipse.exe" "javaw.exe"
set Tmp=Tmp.txt
set LogFile=ProcessKillerLog.txt
If Exist %Tmp% Del %Tmp%
If Exist %LogFile% Del %LogFile%
For %%a in (%process%) Do Call :KillMyProcess %%a %Tmp%
Cmd /U /C Type %Tmp% > %LogFile%
If Exist %Tmp% Del %Tmp%
Start "" %LogFile%
Exit /b

:KillMyProcess
Cls 
echo.
ECHO     **************************************
Echo          Trying to kill "%~1"
ECHO     **************************************                       
(
Echo The Process :  "%~1"  
Taskkill /IM  "%~1" /F /T
Echo =======================
)>>%2 2>&1

如果你想杀死所有 java.exe 进程:Taskkill /F /IM java.exe /Twmic process where "name like '%java%'" delete

【讨论】:

  • 很好的概述,谢谢。目前,我将使用单独的启动配置执行 .bat 文件,其内容为:wmic process where "CommandLine like '%%something from the command line%%'" delete,正如您在评论中所建议的那样。我想避免为停止服务创建单独的启动配置,但它仍然可以完成这项工作。
【解决方案2】:

到目前为止,我发现的最佳解决方法是一个可重复使用的外部应用程序启动器:

import java.lang.ProcessBuilder.Redirect;

public class Main {

    public static void main(String[] args) throws Exception {
        Process process = new ProcessBuilder(args[0])
            .redirectOutput(Redirect.INHERIT)
            .redirectError(Redirect.INHERIT)
            .start();

        Thread thread = new Thread(() -> readInput(args[1]));
        thread.setDaemon(true);
        thread.start();

        process.waitFor();
    }

    private static void readInput(String commandLinePart) {
        try {
            while (System.in.read() != -1);
            killProcess(commandLinePart);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void killProcess(String commandLinePart) throws Exception {
        final String space = " ";
        String[] commandLine = "wmic process where \"commandLine like '%placeholder%'\" delete"
                .replaceAll("placeholder", commandLinePart).split(space);
        new ProcessBuilder(commandLine).start();
    }
}

这个想法是启动这个应用程序而不是外部应用程序,并将有关目标应用程序的信息作为命令行参数传递给它。

启动器应用程序然后启动进程,重定向输出和错误流(以便我在 Eclipse 控制台中看到目标应用程序输出),等待目标进程完成并等待来自标准输入的 EOF。

最后一点确实有效:当我从 Eclipse 控制台终止进程时,标准输入到达 EOF,启动器应用程序也知道是时候停止目标进程了。

Eclipse 外部工具配置对话框现在如下所示:

Location 对于所有配置始终相同,并指向仅运行启动器应用程序的start.bat 文件:

java -jar C:\ExternalProcessManager\ExternalProcessManager.jar %1 %2

它还接受两个命令行参数:

  1. 目标进程(在我的例子中是test.bat,它只是启动我的测试应用程序:java -jar Test.jar)。
  2. 用于启动应用程序的命令行部分(在我的情况下为Test.jar),以便在我从 Eclipse 控制台终止进程时,启动器应用程序可以唯一地识别和终止目标进程。

【讨论】:

    【解决方案3】:

    当您运行外部工具时,它会在 Eclipse 上启动一个控制台。

    您只需在当前 Eclipse 控制台右上角的工具栏上选择并停止该控制台

    1. 显示正在运行的控制台:点击“显示选定的控制台”工具箭头(控制台工具栏右侧的小型计算机)。
    2. 选择外部应用程序控制台:点击运行应用程序的命令所在的行(下拉菜单)。
    3. 停止应用程序:点击停止按钮(控制台工具栏左侧的红色方块)。

    Eclipse console toolbar with a red circle on the "display selected console" tool and a blue circle is the "stop" tool

    【讨论】:

      猜你喜欢
      • 2010-10-01
      • 2015-11-07
      • 1970-01-01
      • 2017-09-12
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多