2017-04-17 1 views
0

私はインターネット上で多くを検索しましたが、誰も何らかのリインドリターン入力の例を成功させることはできません。以下の私のコードでは、コマンド "ipconfig"または "192.168.0.10"を実行したときに正しい出力が得られました。しかし、 "ipconfig"の代わりにコマンド "ftp"を実行すると、コンソールである子プロセスが次の入力コマンドを待っています。この場合、11111を入力としてコンソールに書き込もうとしました。しかし、コンソールは私の入力コマンドを受信せず、入力コマンドを永久に待っていませんでした。どのようにすることができます私は正常に応答、このプログラムでは、「FTP」コマンドへとどのように私はcreateprocess reindirect input successを成功させることができますか?私はsuccessally reindirect out put結果を得ることができます

#include <windows.h> 
#include <fstream> 
using namespace std; 

int WINAPI WinMain(
        HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPSTR lpComLine, 
        int nCmdShow) 
{ 
    SECURITY_ATTRIBUTES secAttr; 
    HANDLE hRead,hWrite; 

char command[256]; 
char testBuf[256] = {0}; 
    strcpy(command, "ipconfig"); 
// strcpy(command, "ping 192.168.0.10")  
// strcpy(command, "ftp"); 

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

HANDLE hTxtFile = CreateFile("tmp.txt", GENERIC_ALL, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
if (hTxtFile == INVALID_HANDLE_VALUE) 
{ 
    MessageBox(NULL, "Error createfile", NULL, MB_OK); 
    return 0; 
} 
HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_WRITE, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
if (hWriteFile == INVALID_HANDLE_VALUE) 
{ 
    MessageBox(NULL, "Error createWritefile", NULL, MB_OK); 
    return 0; 
} 

STARTUPINFO startupInfo; 
PROCESS_INFORMATION processInfo; 
startupInfo.cb = sizeof(STARTUPINFO); 
GetStartupInfo(&startupInfo); 
startupInfo.hStdError = hTxtFile;  
startupInfo.hStdOutput = hTxtFile; 
startupInfo.hStdInput = hWriteFile; 
startupInfo.wShowWindow = SW_SHOW; 
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; 

char output[10240] = {0}; 
DWORD bytesRead; 

if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&startupInfo,&processInfo)) 
{ 
    MessageBox(NULL, "Error createprocess", NULL, MB_OK); 
    CloseHandle(hWrite); 
    CloseHandle(hRead); 
    return FALSE; 
} 

DWORD processExitCode = 0; 
strcpy(testBuf, "11111\r\n"); 
while (GetExitCodeProcess(processInfo.hProcess, &processExitCode)) 
{ 
    WriteFile(hWriteFile, testBuf, 7, &bytesRead, NULL); 
    if (processExitCode != STILL_ACTIVE) 
    { 
     // MessageBox(NULL, "End process", NULL, MB_OK); 
     break; 
    } 
    Sleep(1000); 
} 

SetFilePointer(hTxtFile, NULL, NULL, FILE_BEGIN); 
ReadFile(hTxtFile, output, 10240, &bytesRead, NULL); 
CloseHandle(hTxtFile); 

MessageBox(NULL, output, NULL, MB_OK); 

return 0; 
} 
+0

1)あなたが近くないハンドルは、2) 'hStdInput'は' FILE_GENERIC_READ'アクセス3を持っている必要がありますする必要が)ほとんどのプログラムビュー空の入力( 'NumberOfBytesReadはの== 0 'または* ZwReadFile *リターン*のSTATUS_END_OF_FILE *)単に終了してください。そうすれば、あなたのコードはファイルシステムファイルで動作しなくなります。プロセスを作成する前に 'hStdInput' *にデータを書き込む必要があります。 – RbMm

+0

4)一般的な注意 - 同期共有ファイルを使用する際に使用する - 間違った - ファイル共有* CurrentByteOffset *。 * WriteFile *を呼び出すと、子プロセスが位置を変更する可能性があるため、あなたが考える位置から書き込むことはできません(これは* OVERLAPPED *で直接オフセットを使用することで回避できます)。あなたの書き込み変更*共有ファイルオブジェクトのCurrentByteOffset *と子プロセスに影響する5) 'processExitCode!= STILL_ACTIVE'を100%信頼できる方法で使用しない - ' ExitProcess(STILL_ACTIVE) 'を呼び出すとどうなりますか? – RbMm

+0

私のプロジェクトではすでに問題が見つかりました。そのため、基本的にはSTARTF_USESTDHANDLESプロパティを使用します。 create processは非対話型コンソールを作成します。つまり、create process呼び出しで1つのコマンドラインしか実行できません。任意のアイデアを私は最後のコンソール出力に応じてユーザー入力を取る対話型のリダイレクトコンソールを作成するcreateprocessを使用できますか?ありがとうございました –

答えて

2

リダイレクト(「reindirecting」ではない)を実行しているコンソールを続けるの入力は、出力をリダイレクトするようにちょうど同じように動作します。もちろん、データの流れは反対方向です。これは、プロセスがファイルからを読み込むことを意味します。あなたが書き込み用のハンドルを開いたときに、サンプルコードではそうであるようにこれは、順番に、意味:

HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_WRITE, ...); 

プロセスがすることができなくなり、それからをお読みください。あなたは読書のためにファイルを開く必要があります。

HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_READ, ...); 

しかし、その後、これはまた、あなたが事前プロセスまで送りたい入力を準備しなければならないことを意味します。プロセスを作成した後にのファイルに書き込むことは役に立ちません。

事前にプロセスに送信する必要のあるデータがわからない場合は、ファイルを標準入力に使用することはできませんが、(名前付きまたは匿名の)パイプなど、別のものを使用する必要があります。

0

コンソール出力をリダイレクトしてファイルに

1のバッファを記述する必要があります)

/* Create a pipe for the child process's STDOUT */ 
    if(!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
     BAIL_OUT(-1); 

2)

/* Duplicate the pipe HANDLE */ 
    if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) 
     BAIL_OUT(-1); 

3)

CHAR chBuf[BUFSIZE]; 
    DWORD dwRead; 
    DWORD dwAvail = 0; 
    if (!PeekNamedPipe(hChildStdoutRdDup, NULL, 0, NULL, &dwAvail, NULL) || !dwAvail) 
     return; 
    if (!ReadFile(hChildStdoutRdDup, chBuf, min(BUFSIZE - 1, dwAvail), &dwRead, NULL) || !dwRead) 
     return; 
    chBuf[dwRead] = 0; 

見つけてください。詳細はこちら: https://www.codeproject.com/Articles/5531/Redirecting-an-arbitrary-Console-s-Input-Output

+0

http://stackoverflow.com/questions/26398214/redirect-ftp -pipe-in​​-cここで、私のコードを変更し、それは今完全に動作しますが、私はこのOPと同じ問題に遭遇します。実際のコンソールに "ftp"または "wmic"を入力すると、 "ftp>"を受け取り、 "123"のような無効なコマンドを入力すると、 "Invalid command"が表示されます。しかし、この親プロセスと子コンソールプロセスの間のこの対話的な操作は、自分のコードまたはインターネット上で見つけたすべてのリダイレクトプログラムでは発生しません。私はこのデモをダウンロードしていましたが、それを実行したときと同じ問題があります –

関連する問題