PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : cmd.exe ein/ausgabe steuern mit pipes


nilverd
23.01.2005, 17:20
huuuuuhu

ich befasse mich gerade ein wenig damit, ein remote command programm zu schreiben.ich möchte, dass die eingegebenen commands and cmd.exe weitergereicht werden, wo sie ausgeführt werden und dann wieder zurückgesendet werden sollen.

ich weiss, dass ich das mit pipes anstellen muss. ich habe auch schon in der msdn bei pipes geschaut und das beispiel programm dazu studiert, aber ich verstehe immernoch garnichts davon :(


hat jemand vielleicht ein paar tips oder eine seite wo pipes gut erklärt sind ??
danke


mfg
nil


Pukys
24.01.2005, 12:55
ich weiss, dass ich das mit pipes anstellen muss. ich habe auch schon in der msdn bei pipes geschaut und das beispiel programm dazu studiert, aber ich verstehe immernoch garnichts davon :(

Hier habe ich etwas interessantes für dich gefunden -- einmal suchen in den MSDN fördert zuweilen erstaunliches Zutage:


"Creating a Child Process with Redirected Input and Output

The example in this topic demonstrates how to create a child process from a console process. It also demonstrates a technique for using anonymous pipes to redirect the child process's standard input and output handles. Note that named pipes can also be used to redirect process I/O.


The CreatePipe function uses the SECURITY_ATTRIBUTES structure to create inheritable handles to the read and write ends of two pipes. The read end of one pipe serves as standard input for the child process, and the write end of the other pipe is the standard output for the child process. These pipe handles are specified in the SetStdHandle function, which makes them the standard handles inherited by the child process. After the child process is created, SetStdHandle is used again to restore the original standard handles for the parent process.

The parent process uses the other ends of the pipes to write to the child process's input and read the child process's output. The handles to these ends of the pipe are also inheritable. However, the handle must not be inherited. Before creating the child process, the parent process must use DuplicateHandle to create a duplicate of the application-defined hChildStdinWr global variable that cannot be inherited. It then uses CloseHandle to close the inheritable handle. For more information, see Pipes.

The following is the parent process."


#include <stdio.h>
#include <windows.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);

DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;

// Set the bInheritHandle flag so pipe handles are inherited.

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;

// The steps for redirecting child process's STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.

// Save the handle to the current STDOUT.

hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process's STDOUT.

if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");

// Set a write handle to the pipe to be STDOUT.

if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit("Redirecting STDOUT failed");

// Create noninheritable read handle and close the inheritable read
// handle.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd);

// The steps for redirecting child process's STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.

// Save the handle to the current STDIN.

hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

// Create a pipe for the child process's STDIN.

if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");

// Set a read handle to the pipe to be STDIN.

if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
ErrorExit("Redirecting Stdin failed");

// Duplicate the write handle to the pipe so it is not inherited.

fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");

CloseHandle(hChildStdinWr);

// Now create the child process.

fSuccess = CreateChildProcess();
if (! fSuccess)
ErrorExit("Create process failed");

// After process creation, restore the saved STDIN and STDOUT.

if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
ErrorExit("Re-redirecting Stdin failed\n");

if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
ErrorExit("Re-redirecting Stdout failed\n");

// Get a handle to the parent's input file.

if (argc > 1)
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
else
hInputFile = hSaveStdin;

if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("no input file\n");

// Write to pipe that is the standard input for a child process.

WriteToPipe();

// Read from pipe that is the standard output for child process.

ReadFromPipe();

return 0;
}

BOOL CreateChildProcess()
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;

// Set up members of the PROCESS_INFORMATION structure.

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure.

ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);

// Create the child process.

bFuncRetn = CreateProcess(NULL,
"child", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION

if (bFuncRetn == 0) {
ErrorExit("CreateProcess failed\n");
return 0;
} else {
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return bFuncRetn;
}
}
}

VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL)) break;
}

// Close the pipe handle so the child process stops reading.

if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed\n");
}

VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Close the write end of the pipe before reading from the
// read end of the pipe.

if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");

// Read output from the child process, and write to parent's STDOUT.

for (;;)
{
if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
break;
}
}

VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}

nilverd
24.01.2005, 14:32
das war aber das code-example von dem ich gesprochen habe

LowFly
06.08.2006, 18:05
das war aber das code-example von dem ich gesprochen habe

Bin über die suchfunktion über den thread hier gestolpert.
ist das thema für dich noch aktuell:confused:

is jetzt ja schon fast 1 1/2 jahre her aber ich bin auf der suche nach der gleichen lösung wie du. & hab da auch was brauchbares dazu gefunden.

mit dem beispiel aus der msdn kann ich auch nix anfangen da es auch nicht funzt. es bricht immer mit den fehlermeldungen "Creade Process fehlgeschlagen" oder "Creade Child Process fehlgeschlagen" ab.

Hab mich dann mal codeproject umgeschaut und auf anhieb was gefunden.
hier der link zum thread
http://www.codeproject.com/cpp/9505Yamaha_1.asp

sollte das nicht ausreichen einfach mal dort nach CreatePipe suchen

xrayn
16.08.2006, 18:39
FILE *fz;
char *buffer=malloc(512);

fz=popen("help", "r");
while(fgets(buffer,511,fz) != NULL)
{
printf("%s", buffer);
}

So kann man auch die Ausgabe umleiten. Mit printf() wird das Ausgabe vom Befehl "help" halt ausgegeben, man koennte es dieser Stelle aber auch uebers Netzwerk versenden.

TekWarrior
17.08.2006, 13:59
Du solltest vielleicht anmerken, dass popen() eine POSIX (IIRC) Funktion ist, und damit nicht direkt unter Windows zur Verfügung steht. Allerdings gibt es da noch CYGWIN, damit kriegst du dann popen() und weitere POSIX Funktionen auch unter Windows ;).

xrayn
17.08.2006, 15:47
Naja ob es dann immer gleich cygwin sein muss, es wuerde auch reichen sich den LCC-Win32[1] zu downloaden. Der gibt beim kompilieren auch keine Fehler aus, außerdem finde ich, dass er eine nette Benutzeroberflaeche hat ;).

[1]LCC-Win32 - http://www.cs.virginia.edu/~lcc-win32/ (http://www.cs.virginia.edu/%7Elcc-win32/)

mnemonic
17.08.2006, 15:53
[1]LCC-Win32 - http://www.cs.virginia.edu/~lcc-win32/ (http://www.cs.virginia.edu/%7Elcc-win32/)
In dem Zusammenhang möchte ich mal noch PellesC [1] in den Raum werfen.
PellesC ist eine Weiterentwicklung von LCC. Ich habe auch schon mit LCC gearbeitet und oft verflucht.
PellesC bringt viele neue Features (u.A. einen Installer-Generator, Inline Assembler ist nun möglich, etc. pp.) und eine stabile IDE mit, mit der man produktiv arbeiten kann.

[1] PellesC - http://www.smorgasbordet.com/pellesc/