Page 1 of 1

wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 6:30 am
by evstevemd
Hi,
I have a working wxExecute/wxProcess code working fine. But am having hard time to deal with interactive commands. Here is an example of such commmand and how it works on terminal

Code: Select all

rm -rfvi deletedAlready/
examine files in directory deletedAlready/? y
remove deletedAlready//1.txt? n
remove deletedAlready//2.txt? n
remove deletedAlready//3.txt? n
remove deletedAlready//4.txt? n
remove deletedAlready//5.txt? n
remove deletedAlready/? n
You see, it asks for user response. Now I want to present that to user and get the response and write it to output stream. But I cannot figure out that yet. Do wxWidgets have the way to do that or it is just an impossible task?

TIA

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 3:13 pm
by alys666
there are input and output streams of the process. process sends to you text strings via its output stream and reads your text input via process input stream.
see functions GetInputStream, GetOutputStream of the process. one gives you a stream - with read functions(its what the process is writing to you), and the next one gives you a stream with write fuctions - it's what you want to sent to process(all your - yes, no, etc).
it you need to make kinda custom console, you must have a custom thread - reader, which reads the running process output, and dumps it to some text control, and everything you're printing in this text control, you must send to process input stream via its write function, in main application thread.

added: to have process streams redirected(for your usage, as i described above), you must create wxProcess with wxPROCESS_REDIRECT flag, or if I remember call Redirect() function in its constructor.
Alex

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 3:30 pm
by evstevemd
Hi,
alys666 wrote:
Wed Jul 24, 2019 3:13 pm
there are input and output streams of the process. process sends to you text strings via its output stream and reads your text input via process input stream.
see functions GetInputStream, GetOutputStream of the process. one gives you a stream - with read functions(its what the process is writing to you), and the next one gives you a stream with write fuctions - it's what you want to sent to process(all your - yes, no, etc).
I already have a working wxExecute/wxProcess combination
alys666 wrote:
Wed Jul 24, 2019 3:13 pm
it you need to make kinda custom console, you must have a custom thread - reader, which reads the running process output, and dumps it to some text control, and everything you're printing in this text control, you must send to process input stream via its write function, in main application thread.
Alex
I was thinking may be there is a "special" way to do that, so that when I detect that I can show a dialog for user to input the answer. I guess there is no way. So I will have to put the input textctrl and leave for user to answer when the question is asked (on wxTextCtrl where am dumping all process output. But then user can abuse it by typing when there is no question. But I guess I have to live with that!

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 3:56 pm
by alys666
why no way... your reader thread reads output and parses it...if it finds some specific substring or symbol... in your case '?', it sends message to main thread - "user_asks_confirmation"...main thread receives it and opens dialog with buttons "yes"-"no". in button handlers you write "y" or "n" to process input stream.

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 4:32 pm
by evstevemd
alys666 wrote:
Wed Jul 24, 2019 3:56 pm
why no way... your reader thread reads output and parses it...if it finds some specific substring or symbol... in your case '?', it sends message to main thread - "user_asks_confirmation"...main thread receives it and opens dialog with buttons "yes"-"no". in button handlers you write "y" or "n" to process input stream.
That is a good option but only catches ? and assumes that output will not have ? except for the question in need of input.
But I will start with this and keep building as I go.

Thank you!

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Wed Jul 24, 2019 5:48 pm
by alys666
in your particular case you have patterns
examine files in directory*?
remove*?
where asterisk means - any substring.
it's what you have to search

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Thu Jul 25, 2019 3:31 pm
by evstevemd
alys666 wrote:
Wed Jul 24, 2019 5:48 pm
in your particular case you have patterns
examine files in directory*?
remove*?
where asterisk means - any substring.
it's what you have to search
Yes I understand that but I will be adding different commands later.
I will need to investigate the command pattern before adding new one

Thank you for your time and comments

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Sun Sep 15, 2019 1:28 pm
by evstevemd
So I took a shot at it and implemented simple case catching ?
I get prompted and I write back to the stream. But the program hangs. it seems like the console app is not getting my response.
command is:

Code: Select all

rm -i /file/path
Response code inside wxProcess derived class

Code: Select all

void MyProcess::Ask(const wxString &question)
{
    wxString answer = wxGetTextFromUser(question, _("Requesting User Input"));
    if(GetOutputStream() && !answer.IsEmpty()) {
        if(GetOutputStream()->WriteAll(answer.mb_str(), answer.length()))
            SendMessage(answer);
        else
        {
            switch(GetOutputStream()->GetLastError())
            {
                case wxSTREAM_NO_ERROR:
                {
                    wxLogMessage("wxSTREAM_NO_ERROR");
                    break;
                }
                case wxSTREAM_EOF:
                {
                    wxLogMessage("wxSTREAM_EOF");
                    break;
                }
                case wxSTREAM_WRITE_ERROR:
                {
                    wxLogMessage("wxSTREAM_WRITE_ERROR");
                    break;
                }
                case wxSTREAM_READ_ERROR:
                {
                    wxLogMessage("wxSTREAM_READ_ERROR");
                    break;
                }
                default:
                {
                    wxLogMessage("Unknown error");
                }
            }
        }
    }
    else
    {
        wxLogError(_("Could not write your response!"));
    }
}
Am I missing something?

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Mon Sep 16, 2019 7:33 am
by alys666
i'm interacting with GDB in very easy way:

Code: Select all

	void command(const wxString & fs){
		wxTextOutputStream ls(*_process->GetOutputStream());
		ls<<fs<<"\n";
	}
and it works. it sends string <fs>(various GDB commands) to GDB session and everything is ok.
ps. may be you forgot to add '\n' in your code?

Re: wxExecute and wxProcess: Dealing with Interactive commands

Posted: Mon Sep 16, 2019 9:29 am
by evstevemd
alys666 wrote:
Mon Sep 16, 2019 7:33 am
i'm interacting with GDB in very easy way:

Code: Select all

	void command(const wxString & fs){
		wxTextOutputStream ls(*_process->GetOutputStream());
		ls<<fs<<"\n";
	}
and it works. it sends string <fs>(various GDB commands) to GDB session and everything is ok.
ps. may be you forgot to add '\n' in your code?
You got it right. I forgot the new line (how foolish is that!)
Thank you, now it works fine!