如何与C程序内的.exe交互(Windows控制台)?

时间:2019-05-15 12:23:26

标签: c cmd

我试图在另一个C程序中执行以下程序:

// plus2.exe

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int number;
    printf("Enter your Number: ");
    scanf("%d", &number);
    int result = number + 2;
    printf("%d + 2 = %d\n", number, result);
    return 1;
}

我在互联网上找到了以下代码,但是似乎无法正常工作:

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

#define BUFSIZE 4096 

HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;

HANDLE g_hInputFile = NULL;

int CreateChildProcess(TCHAR *szCmdline);

void PrintError(char *text,int err);
int InitPipes();


int WriteToPipe(char* command){
    DWORD dwRead, dwWritten;
    BOOL bSuccess = FALSE;
    SetLastError(0);
    WriteFile(g_hChildStd_IN_Wr, command, strlen(command), &dwWritten, NULL);


    bSuccess=GetLastError();

    PrintError("WriteToPipe",bSuccess);
    return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING);
}

int ReadFromPipe(void){
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];
    BOOL bSuccess = FALSE;
    HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

    SetLastError(0);
    while(
        ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL)
        &&
        WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL)
        );

    bSuccess=GetLastError();
    PrintError("ReadFromPipe",bSuccess);


    return (bSuccess==0)||(bSuccess==ERROR_IO_PENDING);
}

HANDLE hThread;

long unsigned int ThreadProc(void * arg){

    while(ReadFromPipe())
        ;

}

int main(){
    char input_buffer[100] = { 0 };
    if(!InitPipes()){
        printf("Failed to CreatePipes\n");
        return -1;
    }

    if(!CreateChildProcess("plus2.exe")){
        printf("Failed to create child process\n");
        return -2;
    }


    hThread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL);

    while (1){
        fgets(input_buffer, 99, stdin);
        if(!WriteToPipe(input_buffer)) break;
    }
    printf("Program terminated\n");
    return 0;
}





int CreateChildProcess(TCHAR *szCmdline){ 

   PROCESS_INFORMATION piProcInfo; 
   STARTUPINFO siStartInfo;
   BOOL bSuccess = FALSE; 

// Set up members of the PROCESS_INFORMATION structure. 

   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure. 
// This structure specifies the STDIN and STDOUT handles for redirection.

   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO); 
   siStartInfo.hStdError = g_hChildStd_OUT_Wr;
   siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
   siStartInfo.hStdInput = g_hChildStd_IN_Rd;
   siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

// Create the child process. 

   bSuccess = CreateProcess(NULL, 
      szCmdline,     // 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 an error occurs, exit the application. 
   if (  bSuccess ){
      // Close handles to the child process and its primary thread.
      // Some applications might keep these handles to monitor the status
      // of the child process, for example. 

      CloseHandle(piProcInfo.hProcess);
      CloseHandle(piProcInfo.hThread);
   }
    return bSuccess;
}



int InitPipes(){
   SECURITY_ATTRIBUTES saAttr; 

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

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



   if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) 
      return 0;

   if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
      return 0;

   if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
      return 0;

   if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
      return 0; 

    return 1;
}


void PrintError(char *text,int err){
     DWORD retSize;
     LPTSTR pTemp=NULL;

    if(!err) return;

     retSize=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
                           FORMAT_MESSAGE_FROM_SYSTEM|
                           FORMAT_MESSAGE_ARGUMENT_ARRAY,
                           NULL,
                           err,
                           LANG_NEUTRAL,
                           (LPTSTR)&pTemp,
                           0,
                           NULL );


    if(pTemp) printf("%s: %s\n",text,pTemp);
     LocalFree((HLOCAL)pTemp);
    return ;

}

这是我的预期输出:

Enter your Number: 5
5 + 2 = 7

这就是代码在做什么:

5
Enter your Number: 5 + 2 = 7

此外,在执行plus2.exe之后,程序会陷入无限输入循环中。我正在Windows 10上尝试此操作,我不想使用popen()或system(),因为我想发送自动输入并将结果最终存储到文件中。

0 个答案:

没有答案