Bug 499832 - Code snippet to open remote terminal programmatically in eclipse terminals view and execute shell commands programmatically in it
Summary: Code snippet to open remote terminal programmatically in eclipse terminals vi...
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: terminal (show other bugs)
Version: Next   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-17 09:06 EDT by Chandrayya CLA
Modified: 2020-09-04 15:12 EDT (History)
7 users (show)

See Also:


Attachments
Demo with @angular/cli (873.02 KB, image/gif)
2017-02-21 04:16 EST, Angelo ZERR CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chandrayya CLA 2016-08-17 09:06:39 EDT
I am using the below code to open a remote shell in Remote shell view and can able to execute commands in it and can able to read the outputs of these commands.

        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        IStructuredSelection sel = (IStructuredSelection)window.getSelectionService().getSelection();
        RemoteProcessImpl ele = (RemoteProcessImpl)sel.getFirstElement();
        IHost conn = ele.getSystemConnection();
        IRemoteCmdSubSystem cmdSS = RemoteCommandHelpers.getCmdSubSystem(conn);
        Object[] obs = null;
        RemoteOutput fe = null;
        try {
            cmdSS.checkIsConnected(null);
        } catch (SystemMessageException e2) {
            e2.printStackTrace();
        }
        try {
            cmdSS.initializeSubSystem(null);
        } catch (SystemMessageException e1) {
            e1.printStackTrace();
        }
        RemoteCommandShell shell = null;
        try {
            shell = (RemoteCommandShell)cmdSS.getDefaultShell();
        } catch (Exception e) {
            e.printStackTrace();
        }
        shell.removeOutput();
        cmdSS.sendCommandToShell("ls -l", shell, null);
        Thread.sleep(1000);
        obs = new Object[shell.getRoots().length];
        obs = shell.getRoots();
        for (int i = 0; i < obs.length; i++) {
            fe = (RemoteOutput)obs[i];
            String op1 = fe.getText();
            System.out.println(op1);
        }
        command.setLength(0);

I want to do the EXACTLY same thing for remote terminal i.e want to open a remote terminal in Terminals view[Programmatically] and 
execute commands in it[Programmatically] and read the output of the commands executed in the opened terminal.

I have posted the same message here on tm-dev mailing list https://dev.eclipse.org/mhonarc/lists/tm-dev/msg01138.html but no response.

Let me know how to use RSE-TM API's to address this issue.
Comment 1 Greg Watson CLA 2016-08-17 12:04:52 EDT
Do you specifically need the terminal view, or would it be sufficient to be able to run commands on the remote system and read the output?
Comment 2 Chandrayya CLA 2016-08-18 03:42:16 EDT
(In reply to Greg Watson from comment #1)
> Do you specifically need the terminal view, or would it be sufficient to be
> able to run commands on the remote system and read the output?

Yes. I need the terminal view ONLY.I need this because the command to be executed needs user interaction.
For example if I execute 'gdb' command then this gives me gdb prompt[like gdb> ] in which I can enter gdb commands.
Comment 3 Chandrayya CLA 2016-08-23 11:04:37 EDT
Hello Greg and others,
Any updates on this?
Comment 4 Martin Oberhuber CLA 2016-08-23 13:18:49 EDT
The code snippet from comment 0 is for RSE.

If you need a Terminal only, please use the snippet here:
https://dev.eclipse.org/mhonarc/lists/tm-dev/msg01128.html

Tested to work with the TM Terminal (no RSE dependency), as Uwe wrote on the mailing list.
Comment 5 Chandrayya CLA 2016-08-24 09:16:52 EDT
(In reply to Martin Oberhuber from comment #4)
> The code snippet from comment 0 is for RSE.
> 
> If you need a Terminal only, please use the snippet here:
> https://dev.eclipse.org/mhonarc/lists/tm-dev/msg01128.html
> 
> Tested to work with the TM Terminal (no RSE dependency), as Uwe wrote on the
> mailing list.

Hello Martin Oberhuber,
Have you tried this snippet?I think its incomplete one. I am not able to understand it completely.
Please post here the complete working example like calling 'ls' command with -l arg.

1. Which one I need to use 'SshLauncherDelegate', 'RemoteLauncherDelegate', 'ProcessLauncherDelegate' or TerminalsLauncherDelegate for this? 
2. Do I need to call 'createTerminalConnector' method first then call 'execute' method to open the console?

Its not clear to me how to use ITerminalConnectorConstants.PROP_PROCESS_PATH and ITerminalConnectorConstants.PROP_PROCESS_ARGS props to execute commands on remote target.
Comment 6 Uwe Stieber CLA 2016-08-27 08:44:25 EDT
That code works for running a command in the local terminal:

// Define the terminal properties
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(ITerminalsConnectorConstants.PROP_TITLE, "List Directory Content: /tmp");
properties.put(ITerminalsConnectorConstants.PROP_ENCODING, "UTF-8");
properties.put(ITerminalsConnectorConstants.PROP_PROCESS_WORKING_DIR, "/tmp");
properties.put(ITerminalsConnectorConstants.PROP_DELEGATE_ID, "org.eclipse.tm.terminal.connector.local.launcher.local");
properties.put(ITerminalsConnectorConstants.PROP_PROCESS_PATH, "/bin/ls");
properties.put(ITerminalsConnectorConstants.PROP_PROCESS_ARGS, "-la");

// Create the done callback object
ITerminalService.Done done = new ITerminalService.Done() {
    public void done(IStatus done) {
        // Place any post processing here
    }
};

// Open the terminal
ITerminalService terminal = TerminalServiceFactory.getService();
if (terminal != null) terminal.openConsole(properties, done);

For other terminal types, you may not have the capability of launching a process.

>1. Which one I need to use 'SshLauncherDelegate', 'RemoteLauncherDelegate', >'ProcessLauncherDelegate' or TerminalsLauncherDelegate for this? 

You typically select the local terminal delegate. If you want to open a terminal to a remote system, guess the SSH terminal delegate is a good choice. You will have to look at the ITermainlsConnectorConstants interface which properties are valid for SSH terminals. 

>2. Do I need to call 'createTerminalConnector' method first then call 'execute' >method to open the console?

No.

The second part of your request is much more complicated, as the terminal does not yet have a way to listen to the output send from the remote to the terminal. On the other hand, it is not too hard to add this capability to the terminal. Contributions are always welcome.
Comment 7 Chandrayya CLA 2016-08-30 08:12:05 EDT
(In reply to Uwe Stieber from comment #6)
> That code works for running a command in the local terminal:
> 
> // Define the terminal properties
> Map<String, Object> properties = new HashMap<String, Object>();
> properties.put(ITerminalsConnectorConstants.PROP_TITLE, "List Directory
> Content: /tmp");
> properties.put(ITerminalsConnectorConstants.PROP_ENCODING, "UTF-8");
> properties.put(ITerminalsConnectorConstants.PROP_PROCESS_WORKING_DIR,
> "/tmp");
> properties.put(ITerminalsConnectorConstants.PROP_DELEGATE_ID,
> "org.eclipse.tm.terminal.connector.local.launcher.local");
> properties.put(ITerminalsConnectorConstants.PROP_PROCESS_PATH, "/bin/ls");
> properties.put(ITerminalsConnectorConstants.PROP_PROCESS_ARGS, "-la");
> 
> // Create the done callback object
> ITerminalService.Done done = new ITerminalService.Done() {
>     public void done(IStatus done) {
>         // Place any post processing here
>     }
> };
> 
> // Open the terminal
> ITerminalService terminal = TerminalServiceFactory.getService();
> if (terminal != null) terminal.openConsole(properties, done);
> 
> For other terminal types, you may not have the capability of launching a
> process.
> 
> >1. Which one I need to use 'SshLauncherDelegate', 'RemoteLauncherDelegate', >'ProcessLauncherDelegate' or TerminalsLauncherDelegate for this? 
> 
> You typically select the local terminal delegate. If you want to open a
> terminal to a remote system, guess the SSH terminal delegate is a good
> choice. You will have to look at the ITermainlsConnectorConstants interface
> which properties are valid for SSH terminals. 
> 
> >2. Do I need to call 'createTerminalConnector' method first then call 'execute' >method to open the console?
> 
> No.
> 
> The second part of your request is much more complicated, as the terminal
> does not yet have a way to listen to the output send from the remote to the
> terminal. On the other hand, it is not too hard to add this capability to
> the terminal. Contributions are always welcome.

@Uwe
Thanks for the reply. Your code to execute ls command on local terminal is working But, 
Just after opening a terminal in "org.eclipse.tm.terminal.view.ui.view.TerminalsView" view terminal closes immediately and doesn’t gave me a prompt to enter other commands. 
So in the newly opened terminal I can see the executed command output[result of ls -la] but I can't enter any other commands because prompt is not given.

On the contrary when I used SSH terminal the command is not executing[Not displaying the output in the newly opened SSH terminal] but it opens up a new terminal in "org.eclipse.tm.terminal.view.ui.view.TerminalsView" view and PROVIDES me the command prompt to enter other commands.

1. Why in SSH terminal commands are NOT executing?Did I missed any ITerminalsConnectorConstants to set?

I am used the below code to run a command in SSH terminal:

 	IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        IStructuredSelection sel = (IStructuredSelection)window.getSelectionService().getSelection();
        RemoteProcessImpl ele = (RemoteProcessImpl)sel.getFirstElement();
        IHost conn = ele.getSystemConnection();
        // Define the terminal properties
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(ITerminalsConnectorConstants.PROP_TITLE, "SSH terminal at" + conn.getName());
        properties.put(ITerminalsConnectorConstants.PROP_ENCODING, "UTF-8");
        properties.put(ITerminalsConnectorConstants.PROP_PROCESS_WORKING_DIR, "/tmp");
        properties.put(ITerminalsConnectorConstants.PROP_DELEGATE_ID, "org.eclipse.tm.terminal.connector.ssh.launcher.ssh");
        properties.put(ITerminalsConnectorConstants.PROP_PROCESS_PATH, "/bin/ls");
        properties.put(ITerminalsConnectorConstants.PROP_PROCESS_ARGS, "-la");
        properties.put(ITerminalsConnectorConstants.PROP_IP_HOST, conn.getName());
        properties.put(ITerminalsConnectorConstants.PROP_SSH_USER, conn.getDefaultUserId());
        properties.put(ITerminalsConnectorConstants.PROP_SSH_PASSWORD, "");

        // Create the done callback object
        org.eclipse.tm.terminal.view.core.interfaces.ITerminalService.Done done = new org.eclipse.tm.terminal.view.core.interfaces.ITerminalService.Done() {
            public void done(IStatus done) {
                System.out.println("in done");
            }
        };
        /*
         * TerminalsLauncherDelegate kl = new TerminalsLauncherDelegate();
         * kl.execute(properties, done);
         */
        // Open the terminal
        org.eclipse.tm.terminal.view.core.interfaces.ITerminalService terminal = TerminalServiceFactory.getService();
        if (terminal != null) {
            System.out.println("In if");
            terminal.openConsole(properties, done);
        }


2. Instead of tm terminal["org.eclipse.tm.terminal.view.ui.view.TerminalsView"] can I use rse terminal[org.eclipse.rse.internal.terminals.ui.views.TerminalViewer]?
Comment 8 Angelo ZERR CLA 2017-02-21 04:16:48 EST
Created attachment 266912 [details]
Demo with @angular/cli

@Uwe I have tried to use your snippet code, but in my case I need to open a cmd.exe and execute a command. As it's not possible, I have worked on this feature to open a terminal with Angular Wizard, execute a command and interpret the command to open an editor from the generated typescript file.

To do that I have created a CommandTerminalService which extends your TerminalService

If you are interested you can find my work at:

 * https://github.com/angelozerr/typescript.java/tree/master/eclipse/terminal
 * and a smple which consumes CommandTerminalService #executeCommand at 
https://github.com/angelozerr/angular2-eclipse/blob/master/ts.eclipse.ide.angular2.cli/src/ts/eclipse/ide/angular2/internal/cli/launch/AngularCLILaunchConfigurationDelegate.java#L73

IMHO I think terminal should provide this feature.
Comment 9 Jonah Graham CLA 2020-05-01 10:09:46 EDT
The Terminal component of the Eclipse Ecosystem has a new home. The Terminal is now part of the Eclipse CDT project[1].

This change means a new Git repo[2], P2 site[3] and Bugzilla component. The terminal will continue to be delivered as part of the quarterly Simultaneous Release of Eclipse as well.

The marketplace entry[4] had not been updated in a few years. It will once again install the latest release of the terminal on the latest release of the whole IDE (currently 2020-03).

If this bug is no longer relevant, please feel free to comment or close the bug. If you can confirm if this issues still occurs in the latest release please do let me know in a comment.

[1] https://wiki.eclipse.org/CDT/User/NewIn911
[2] https://git.eclipse.org/c/cdt/org.eclipse.cdt.git (in the terminal directory)
[3] current release is 9.11 - P2 site https://download.eclipse.org/tools/cdt/releases/9.11/
[4] https://marketplace.eclipse.org/content/tm-terminal

(This comment was added to all open terminal bugs along with changing the Product/component pair to CDT/terminal.)