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);
添加到构造函数的末尾
- 在正确的位置触发
DebugEvent
s(在创建、终止和更改属性时)
- 实施
getAdapter
以适应接收 IProcess
、IDebugTarget
、ILaunch
和 ILaunchConfiguration
如果您执行所有这些操作,您将在启动 IProcess
时看到 ProcessConsole
。
我有一个自定义启动配置,实现了 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);
添加到构造函数的末尾 - 在正确的位置触发
DebugEvent
s(在创建、终止和更改属性时) - 实施
getAdapter
以适应接收IProcess
、IDebugTarget
、ILaunch
和ILaunchConfiguration
如果您执行所有这些操作,您将在启动 IProcess
时看到 ProcessConsole
。