简体   繁体   English

Eclipse插件:如何显示具有自定义启动配置和流程的启动流程控制台?

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

I have a custom launch configuration, implementing ILaunchConfigurationDelegate . 我有一个自定义启动配置,实现了ILaunchConfigurationDelegate I create a new IProcess via DebugPlugin.newProcess . 我通过DebugPlugin.newProcess创建一个新的IProcess I have a custom process factory, too, so I get an instance of my custom IProcess . 我也有一个自定义流程工厂,因此我得到了自定义IProcess的实例。 I then write to the process's output stream monitor: 然后,我写到进程的输出流监视器:

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();
    }
}

This all works fine, but one thing does not occur: A console doesn't appear. 一切正常,但不会发生任何事情:不会出现控制台。 I can make a custom console appear like this: 我可以使自定义控制台显示如下:

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

But this isn't a ProcessConsole , which is what the Launch API should be providing me. 但这不是ProcessConsole ,这是Launch API应该提供给我的。 It's not doing it automatically, and it's standard procedure for launches to use such a console, so I know I have to get one to show up somehow. 它不是自动执行的,它是启动使用这种控制台的标准过程,所以我知道我必须找到一个以某种方式显示。 It's marked as internal, so I shouldn't be making one manually, I don't think. 它被标记为内部,所以我不认为应该手动制作。 Furthermore, DebugUITools.getConsole always returns null . 此外, DebugUITools.getConsole始终返回null

I have a feeling this is because I'm forgetting to do something in my custom IProcess : 我觉得这是因为我忘记在自定义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));
    }
}

So, in short, how do I get a ProcessConsole to appear? 因此,简而言之,如何使ProcessConsole出现? Is it even possible to do this when you use a nonstandard IProcess ? 当您使用非标准的IProcess时,甚至可以这样做吗?

To get the correct functionality for your process, you shouldn't implement IProcess directly; 为了获得正确的功能,您不应该直接实现IProcess you should extend RuntimeProcess instead. 您应该改为扩展RuntimeProcess It has all the methods you need to properly activate the console view. 它包含正确激活控制台视图所需的所有方法。

However, if you wish to implement IProcess directly, there are some things you need to do: 但是,如果您希望直接实现IProcess ,则需要做一些事情:

  • Add getLaunch().addProcess(this); 添加getLaunch().addProcess(this); to the end of your constructor 到构造函数的末尾
  • Fire DebugEvent s in the correct locations (on creation, termination, and the change of an attribute) 在正确的位置(在创建,终止和更改属性时) DebugEvent
  • Implement getAdapter to adapt on receiving an IProcess , IDebugTarget , ILaunch , and ILaunchConfiguration 实现getAdapter以适应于接收IProcessIDebugTargetILaunchILaunchConfiguration

If you do all these things, you'll get the ProcessConsole to appear when you start up your IProcess . 如果执行所有这些操作,则将在启动IProcess时显示ProcessConsole

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM