Sending characters to STDIN in a mode 2 shell on Windows

Hi @William Yu / @Joe Ranieri , can we please get some attention to <https://xojo.com/issue/53182>. This is really causing issues with my Windows projects. I have to be able to send signals to helper apps without killing their parent shell process.

I suggest adding a simple project to the ticket so they can quickly see the problem.

It’s tough to come up with a simple example in my case.

Please revisit the Feedback report on this as it’s worse than originall thought in that NOTHING sent to STDIN in the dynamic (mode = 2) shell is seen by the shelled task.

<https://xojo.com/issue/53182>

I also changed the name of this thread since it’s not signals but rather anything sent to stdin (Shell.Write or Shell.WriteLine).

Perhaps this might help somewhat

And this:
http://documentation.xojo.com/api/os/shell.html#shell-canonical

The Xojo Shell isn’t a “Console” process in this definition as I understand it.

Canonical is set.

GenerateConsoleCtrlEvent function

Again, the Xojo Shell is not a Windows Console. It uses the CreateProcessA/W API IIRC.

[quote=413322:@Tim Jones]The Xojo Shell isn’t a “Console” process in this definition as I understand it.

Canonical is set.[/quote]

If you start a console application using the shell class in mode 2 your app is it’s parent.

If you need control over other processess or sub-processess of other applications, i don’t think you can with xojo itself maybe with a plugin

On Windows, how can I gracefully ask a running program to terminate?

I just had a quick look at this, bit awkward to do much if shell.pid returns a value that seemingly isn’t the PID of the shelled process. Anyone know what it is if its not that?

The shell.pid is invalid because does not match any running process but, for sure, can be valid for a new feedback case.
taskkill can refer the process using the executable name so it works if the shelled process does not run in multiple copies.

A better solution is to use win32 declares.

IIRC, it’s a handle to the process rather than the PID.

Ah yes, that’s the ticket, good spot. I’ll have a tinker after dinner, cheers.

So the PID of the process is:

Soft Declare Function GetProcessId Lib "Kernel32" ( handle as Integer) As integer dim Pid As Integer = GetProcessId(sh.PID)

Please note that the pid refers to the “cmd.exe” the framework spawn to start the command in sh.execute().
So passing the resulting pid to taskkill in some cases (depends on the shelled process behaviour) terminates the spawned “cmd.exe” but not the execute() process.

So in some cases a bit of win32 declares are still required.

@Tim Jones
Post here if you need the code required to walk the process family tree using declares.

Actually, Christian’s MBS toolset provides the solution with his WindowsProcessMBS as shown in his Windows Shell example.

I got sidetracked after dinner =\

Oh, I thought you wanted to keep the shell running and just stop the process that you spawned inside the shell so you could reuse the shell?

The demo you mention is just TerminateProcess’ing the shell which stops anything inside it. If it works for what you need then you’re good to go with, without a bit of testing I have no idea if its gracefully stopping the process sent to it via stdinput or just pulling the rug out under it which could be bad if its anything more complicated than just a dir.

I had found this https://github.com/alirdn/windows-kill which will remotely send signals to processes to gracefully stop them, there’s source code in there too which could be converted to xojo or you could just ship the exe and use it via another shell. You’d just need a few calls to traverse the process list and find the dir with a parent process ID of the cmd as it would be a different process id to the one found through shell.pid as Maurizio mentioned above. But you don’t need to go to that length if you’re happy with the MBS implementation :slight_smile:

PS. I tried that window-kill program at that link and it worked perfectly, stopping the dir and keeping the shell active.

Windows-kill on github replicates what the taskkill.exe command does.