Vister26 Temat założony przez niniejszego użytkownika |
[WinAPI] Przekazywanie poleceń do programu uruchomionego przez CreateProcess » 2017-02-16 00:35:07 Mój program w oddzielnym procesie ma uruchomić cmd i przekazywać do niego polecenia. PROCESS_INFORMATION pi; STARTUPINFO si;
ZeroMemory( & pi, sizeof( pi ) ); ZeroMemory( & si, sizeof( si ) ); si.cb = sizeof( si );
if( !CreateProcess( NULL, ( LPSTR ) "cmd.exe", NULL, NULL, FALSE, 0, NULL, NULL, & si, & pi ) )
WaitForSingleObject( pi.hProcess, INFINITE );
W jaki sposób mam obsługiwać input i output wewnątrz programu? |
|
j23 |
» 2017-02-16 11:19:52 Do jednego z wątków napisałem funkcję, która odpala cmd z przekierowanym i/o. Poszukaj, może coś tam znajdziesz dla siebie. |
|
Vister26 Temat założony przez niniejszego użytkownika |
» 2017-02-16 21:19:28 Niestety wyszukiwanie postów danego użytkownika działa niezbyt sprawnie. Z poniższych źródeł udało mi się zmontować trochę kodu. launch an exe/process with stdin stdout and stderr? Creating a Child Process with Redirected Input and OutputZmieniłem tez koncepcję - zamiast do cmd input ma być przekierowany do program.exe Próbuję do tego użyć windows pipe'ów. Proces działa, odbiera komendy wpisane z klawiatury ale te wysłane przez printf są ignorowane #include <windows.h> #include <stdio.h> #include <tchar.h> #include <process.h> #include <iostream>
#define BUFSIZE 4096
CHAR chBuf[ BUFSIZE ]; DWORD dwRead, dwWritten; HANDLE hStdin, hStdout; BOOL bSuccess;
using namespace std;
STARTUPINFO siEngine; PROCESS_INFORMATION piEngine;
void WriteToPipe( void ); void CreateEngineProcess();
int main() { hStdout = GetStdHandle( STD_OUTPUT_HANDLE ); hStdin = GetStdHandle( STD_INPUT_HANDLE ); if( ( hStdout == INVALID_HANDLE_VALUE ) || ( hStdin == INVALID_HANDLE_VALUE ) ) ExitProcess( 1 ); CreateEngineProcess(); printf( "START 15\r\n" ); WriteToPipe(); WaitForSingleObject( piEngine.hThread, INFINITE ); CloseHandle( piEngine.hProcess ); CloseHandle( piEngine.hThread ); return 0; }
void CreateEngineProcess() { BOOL bSuccess = FALSE; ZeroMemory( & siEngine, sizeof( siEngine ) ); siEngine.cb = sizeof( siEngine ); ZeroMemory( & piEngine, sizeof( piEngine ) ); siEngine.cb = sizeof( STARTUPINFO ); siEngine.hStdOutput = hStdout; siEngine.hStdInput = hStdin; siEngine.dwFlags |= STARTF_USESTDHANDLES; if( !CreateProcess( "program.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, & siEngine, & piEngine ) ) return; }
void WriteToPipe( void ) { bSuccess = ReadFile( hStdin, chBuf, BUFSIZE, & dwRead, NULL ); if( !bSuccess || dwRead == 0 ) cout << "-1" << endl; bSuccess = WriteFile( hStdout, chBuf, dwRead, & dwWritten, NULL ); if( !bSuccess ) cout << "-2" << endl; }
|
|
jankowalski25 |
» 2017-02-16 21:36:55 |
|
Vister26 Temat założony przez niniejszego użytkownika |
» 2017-02-16 21:53:51 Dziękuję! @j23: Proszę jeszcze o jakieś wskazówki jak przerobić tą funkcję aby przekazywała ten argument do innego programu i żeby po wykonaniu polecenia nie był on natychmiast zamykany tylko dalej czekał w procesie na kolejne polecenia. Trochę mnie przerasta konstrukcja tej funkcji i sam nie podołam |
|
j23 |
» 2017-02-17 11:41:55 @jankowalski25, tak, o ten temat mi chodziło.
@Vister26, nie jestem pewien, czy cmd jest w stanie przyjmować komendy strumieniowo przez standardowe wejście. O ile dobrze pamiętam, podczas pisania tamtej funkcji próbowałem wysyłać komendy na wejście, ale to nie działało. Być może trzeba użyć jakiejś dodatkowej opcji przy uruchomieniu cmd.exe. |
|
Vister26 Temat założony przez niniejszego użytkownika |
» 2017-02-17 23:10:05 Przeszukałem większość tematów na Stackoverflow odnośnie tego problemu i mam działający program #include <windows.h> #include <tchar.h> #include <stdio.h> #include <iostream> #include <string>
#define BUFSIZE 4096
HANDLE hEngineStd_IN_Rd = NULL; HANDLE hEngineStd_IN_Wr = NULL; HANDLE hEngineStd_OUT_Rd = NULL; HANDLE hEngineStd_OUT_Wr = NULL;
using namespace std;
void CreateEngineProcess( void ); void WriteToPipe( string msg ); void ReadFromPipe( void );
int main() { SECURITY_ATTRIBUTES saAttr; printf( "\n->Start of parent execution.\n" ); saAttr.nLength = sizeof( SECURITY_ATTRIBUTES ); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if( !CreatePipe( & hEngineStd_OUT_Rd, & hEngineStd_OUT_Wr, & saAttr, 0 ) ); if( !SetHandleInformation( hEngineStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0 ) ); if( !CreatePipe( & hEngineStd_IN_Rd, & hEngineStd_IN_Wr, & saAttr, 0 ) ); if( !SetHandleInformation( hEngineStd_IN_Wr, HANDLE_FLAG_INHERIT, 0 ) ); CreateEngineProcess(); WriteToPipe( "START 15\r\n" ); ReadFromPipe(); WriteToPipe( "BEGIN\r\n" ); ReadFromPipe(); printf( "\n->End of parent execution.\n" ); return 0; }
void CreateEngineProcess()
{ TCHAR szCmdline[] = TEXT( "program.exe" ); PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; ZeroMemory( & piProcInfo, sizeof( PROCESS_INFORMATION ) ); ZeroMemory( & siStartInfo, sizeof( STARTUPINFO ) ); siStartInfo.cb = sizeof( STARTUPINFO ); siStartInfo.hStdError = hEngineStd_OUT_Wr; siStartInfo.hStdOutput = hEngineStd_OUT_Wr; siStartInfo.hStdInput = hEngineStd_IN_Rd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; bSuccess = CreateProcess( NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL, & siStartInfo, & piProcInfo ); if( !bSuccess ); else { CloseHandle( hEngineStd_OUT_Wr ); CloseHandle( hEngineStd_IN_Rd ); CloseHandle( piProcInfo.hProcess ); CloseHandle( piProcInfo.hThread ); } }
void WriteToPipe( string msg ) { BOOL bSuccess; bSuccess = WriteFile( hEngineStd_IN_Wr, msg.c_str(), msg.size(), NULL, NULL ); }
void ReadFromPipe( void ) { DWORD dwRead, dwWritten, dwAvailableBytes, dwBytesLeft; CHAR chBuf[ BUFSIZE ]; BOOL bSuccess = FALSE; HANDLE hParentStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); bSuccess = PeekNamedPipe( hEngineStd_OUT_Rd, chBuf, BUFSIZE, & dwRead, & dwAvailableBytes, & dwBytesLeft ); bSuccess = ReadFile( hEngineStd_OUT_Rd, chBuf, dwAvailableBytes, & dwRead, NULL ); bSuccess = WriteFile( hParentStdOut, chBuf, dwRead, & dwWritten, NULL ); }
Może ktoś kiedyś skorzysta z tego kodu ;) Temat zamykam. |
|
« 1 » |