Re: controlling cmd.exe via named pipes



toottifrootti@xxxxxxxx wrote:
<I've already posted this same discussion on
it.comp.lang.delphi and borland.public.delphi.language.delphi.general
without
receiving answer as I hoped to, so I re-post it here, hoping this
doesn't offend
any groups' netiquette. If so, I'm sorry.>

Why does no one respond to messages I post to Borland’s newsgroups?
http://www.cs.wisc.edu/~rkennedy/borland-newsgroups

I'm trying to use CreateProcess API to launch an "invisible" instance
of cmd.exe and control it via named pipes.

In order to do so, I use TPipeServer and TPipeClient components which
can be found on Russell's Delphi Pages
(http://users.adelphia.net/~rllibby/source.html), Pipes.zip file.
I use them to avoid handling named pipes directly by Windows
Pipes API. You could say this is discussible, anyway let's go on.

This is how I proceed:

1-I create two different named pipes, say 'cmdIN' and 'cmdOUT';

2-as suggested in th following thread ( http://tinyurl.com/2pmls6 ),
I
fill in a STARTUPINFO structure in the appropriate way, and then I
create the cmd.exe process:
=============================
stupinfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
stupinfo.hStdInput := <handle to the 'cmdIN' serverside,obtained from
the wrapping TPipeServer>
stupinfo.hStdOutput := <handle to the 'cmdOUT' clientside, obt from
the wrapping TPipeClient>
stupinfo.hStdError := <as above>
stupinfo.wShowWindow := SW_HIDE;

proc_name := 'C:\WINDOWS\system32\cmd.exe';

I hope that's not your real code. My computer doesn't even have a C: drive, and my OS directory is not named Windows.

If you want to know the name of the system's command interpreter, read the COMSPEC environment variable.

proc_string := '/K';

That's the command switch that tells Cmd to run the command on the command line, and then wait for more commands. If there is no command on the command line, then there's no reason to use /k. Run the program without any parameters, just as though you had double-clicked it in Explorer.

hcp := CreateProcess(proc_name, proc_string, nil, nil, TRUE, 0, nil,
nil, stupInfo, info);

A name like hcp suggests that the variable holds a handle value. CreateProcess returns a Bool, not a handle.

if hcp then WaitForSingleObject(info.hProcess, 3000);

Why are you waiting 3 seconds for the program to terminate, and then not paying attention to whether the program has actually terminated?

=============================

3-from my GUI application, I control the serverside of 'cmdOUT' and
the clientside of 'cmdIN';
I then send (using a TEdit) commands meant for cmd.exe writing on the
second one, catching on the first one the incoming message events,
and
finally copying these messages on a TMemo.

As soon as the process is created, on the memo an "Invalid handle"
message appears,

Messages don't just appear. What is the cause of that message? Where does it come from? Any indication of what handle it's talking about?

and from then on, cmd.exe does not react to commands
I send to it, eve though it receives them.

And I say "even though it receives them" because I also catch
incoming
message events on the serverside of 'cmdIN': commands regularly reach
the other end of the pipe, but they do not have any effect at all,
even if cmd.exe is still alive, as task manager allows to verify.

So, you're sending stuff to the command interpreter, and you're receiving responses. Then what's the problem? What effect are your commands supposed to have, and how are you observing them?

I suppose the cause's the following.
Both the TPipeServer that wraps 'cmdIN' serverside and similarly the
TPipeClient that wraps 'cmdOUT' clientside have a thread dedicated to
listening incoming messages. Maybe
duplicating handles to those pipe sides would be better than passing
to cmd.exe the handles owned by those threads.

Threads don't own handles.

The threads are important, though, since without them you'd get deadlock.

Anyway -I'm sorry for my long, complicated and a bit dazed thread-,
can anyone help me?
Is my last guess correct, and if so, how to correctly duplicate those
handle?

Call DuplicateHandle. Make sure the new handle values are inheritable. Both the source and target processes will be your program's process. You can duplicate them into Cmd's process because that process doesn't exist yet. Duplicate them in your own process, and pass the new handles to CreateProcess.

Res := DuplicateHandle(GetCurrentProcess, cmdIn, GetCurrentProcess, NewCmdIn, 0, True, Duplicate_Same_Access);
Win32Check(Res);

--
Rob
.



Relevant Pages

  • Re: parenthetical grouping
    ... it takes two named pipes as ... > the program just copies from src to dst, except upon opening dst (and before ... or only from the file named on the command line? ...
    (comp.unix.shell)
  • Re: [PHP] Cannot connect to an MySQL database using Named Pipes (resolved)
    ... I have a database running on Window XP, that I want to disable network connections to and enable 'named pipes'. ... I have tried several variants of the connect command and I get various errors but all are along the lines of: ... Can't connect to MySQL server on 'localhost' ... $mysqli = new mysqli("localhost", $username,$password, ...
    (php.general)
  • How to set Named Pipe permssions for non-admin access?
    ... I'm revising a chat application to use named pipes. ... I have it working fine from two command lines running as administrator ... But in production it will be launched from a service ...
    (microsoft.public.win32.programmer.networks)
  • INSERT INTO Not working correctly
    ... I have a command button that does a "Copy" but more of a INSERT INTO command ... Dim strSql As String 'SQL statement. ... 'Make sure there is a record to duplicate. ... !PhaseComplDateReqPlan = Me.PhaseComplDateReqPlan ...
    (microsoft.public.access.formscoding)
  • Re: Cannot Browse the Domain in the Network Neighborhood
    ... Explanation of command ... > duplicate SPN's listed where the event log's say they should be. ... > one of the alleged duplicate SPN's is the name of my domain controller. ... >> With respect to the KDC errors are you referring to KDC event id 11's? ...
    (microsoft.public.windows.server.sbs)