Eclipse 插件:如何使用自定义启动配置和流程显示用于启动的 ProcessConsole?

Eclipse plugin: How to show a ProcessConsole for a launch with a custom launch configuration and process?

我有一个自定义启动配置,实现了 ILaunchConfigurationDelegate。我通过 DebugPlugin.newProcess 创建了一个新的 IProcess。我也有一个自定义流程工厂,所以我得到了一个自定义 IProcess 的实例。然后我写入进程的输出流监视器:

public class MyLauncher implements ILaunchConfigurationDelegate {
    @Override
    public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
        if (monitor == null) monitor = new NullProgressMonitor();

        // launch a new process
        MyProcess process = DebugPlugin.newProcess(launch, null, configuration.getName()).getAdapter(MyProcess.class);
        if (process == null) {
            // ERROR
            throw new CoreException(new Status(Status.ERROR, MyPlugin.ID, "Process factory not configured correctly in the launch configuration"));
        }

        process.out.append("Hello, World!\n");

        process.terminate();
    }
}

一切正常,但没有发生一件事:没有出现控制台。我可以使自定义控制台显示如下:

MyConsole console = /*code to make a custom console here*/;
console.activate();
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] {console});

但这不是 ProcessConsole,Launch API 应该提供给我的。它不会自动执行,使用这样的控制台是启动的标准程序,所以我知道我必须让一个以某种方式出现。它被标记为内部,所以我不应该手动制作一个,我不认为。此外,DebugUITools.getConsole 总是 returns null.

我感觉这是因为我忘记在我的习惯中做一些事情 IProcess:

public class MyProcess implements IProcess {
    private ILaunch launch;
    private String label;
    private IStreamsProxy proxy;
    private Map<String, String> attributes;
    private boolean terminated;
    public MyOutputStream out;

    public MyProcess(ILaunch launch, String label, Map<String, String> attributes) {
        this.launch = launch;
        this.label = label;
        this.attributes = attributes;

        out = new MyOutputStream();

        proxy = new IStreamsProxy() {
            @Override
            public void write(String input) throws IOException {

            }

            @Override
            public IStreamMonitor getOutputStreamMonitor() {
                return out;
            }

            @Override
            public IStreamMonitor getErrorStreamMonitor() {
                return out;
            }
        };
    }

    @Override
    public <T> T getAdapter(Class<T> adapter) {
        if (adapter.equals(MyProcess.class)) {
            return (T) this;
        }

        return null;
    }

    @Override
    public boolean canTerminate() {
        return true;
    }

    @Override
    public boolean isTerminated() {
        return terminated;
    }

    @Override
    public void terminate() throws DebugException {
        launch.terminate();
        terminated = true;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public ILaunch getLaunch() {
        return launch;
    }

    @Override
    public IStreamsProxy getStreamsProxy() {
        return proxy;
    }

    @Override
    public void setAttribute(String key, String value) {
        attributes.put(key, value);
    }

    @Override
    public String getAttribute(String key) {
        return attributes.get(key);
    }

    @Override
    public int getExitValue() throws DebugException {
        return 0;
    }
}

public class MyOutputStream implements IStreamMonitor {
    private String contents = "";
    private List<IStreamListener> listeners = new ArrayList<>();

    @Override
    public void addListener(IStreamListener listener) {
        listeners.add(listener);
    }

    @Override
    public String getContents() {
        return contents;
    }

    @Override
    public void removeListener(IStreamListener listener) {
        listeners.remove(listener);
    }

    public void append(Object o) {
        contents += o;
        listeners.stream().forEach((l)->l.streamAppended(String.valueOf(o), this));
    }
}

所以,简而言之,如何让 ProcessConsole 出现?当您使用非标准 IProcess?

时,甚至可以这样做吗?

要为您的流程获得正确的功能,您不应该直接实施 IProcess;您应该改为扩展 RuntimeProcess 。它具有正确激活控制台视图所需的所有方法。

但是,如果您希望直接实施 IProcess,您需要做一些事情:

  • getLaunch().addProcess(this); 添加到构造函数的末尾
  • 在正确的位置触发 DebugEvents(在创建、终止和更改属性时)
  • 实施 getAdapter 以适应接收 IProcessIDebugTargetILaunchILaunchConfiguration

如果您执行所有这些操作,您将在启动 IProcess 时看到 ProcessConsole