zoukankan      html  css  js  c++  java
  • c# c++通信--命名管道通信

    进程间通信有很多种,windows上面比较简单的有管道通信(匿名管道及命名管道)

    最近做个本机c#界面与c++服务进行通信的一个需求。简单用命名管道通信。msdn都直接有demo,详见下方参考。

    c++:LPTSTR lpszPipename = TEXT("\\.\pipe\mynamedpipe"); 
    c#:new NamedPipeClientStream("localhost", "mynamedpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None))

    c# client端代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    using System.IO.Pipes;
    using System.Security.Principal;
    
    namespace ConsoleApplication4
    {
        class Program
        {
            private static void SendData()
            {
                try
                {
                    using (NamedPipeClientStream pipeClient =
                  new NamedPipeClientStream("localhost", "mynamedpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None))
                    {
                        pipeClient.Connect();
                        using (StreamWriter sw = new StreamWriter(pipeClient))
                        {
                            sw.WriteLine("c:\test\test.doc");
                            sw.Flush();
    
                        }
                        
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
            }
            static void Main(string[] args)
            {
                Console.WriteLine("send data start");
                SendData();
                Console.WriteLine("send data end");
                
            }
        }
    }
    

     c++:

    #include <windows.h> 
    #include <stdio.h> 
    #include <tchar.h>
    #include <strsafe.h>
    
    #define BUFSIZE 512
     
    DWORD WINAPI InstanceThread(LPVOID); 
    VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD); 
     
    int _tmain(VOID) 
    { 
       BOOL   fConnected = FALSE; 
       DWORD  dwThreadId = 0; 
       HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 
       LPTSTR lpszPipename = TEXT("\\.\pipe\mynamedpipe"); 
     
    // The main loop creates an instance of the named pipe and 
    // then waits for a client to connect to it. When the client 
    // connects, a thread is created to handle communications 
    // with that client, and this loop is free to wait for the
    // next client connect request. It is an infinite loop.
     
       for (;;) 
       { 
          _tprintf( TEXT("
    Pipe Server: Main thread awaiting client connection on %s
    "), lpszPipename);
          hPipe = CreateNamedPipe( 
              lpszPipename,             // pipe name 
              PIPE_ACCESS_DUPLEX,       // read/write access 
              PIPE_TYPE_MESSAGE |       // message type pipe 
              PIPE_READMODE_MESSAGE |   // message-read mode 
              PIPE_WAIT,                // blocking mode 
              PIPE_UNLIMITED_INSTANCES, // max. instances  
              BUFSIZE,                  // output buffer size 
              BUFSIZE,                  // input buffer size 
              0,                        // client time-out 
              NULL);                    // default security attribute 
    
          if (hPipe == INVALID_HANDLE_VALUE) 
          {
              _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.
    "), GetLastError()); 
              return -1;
          }
     
          // Wait for the client to connect; if it succeeds, 
          // the function returns a nonzero value. If the function
          // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 
     
          fConnected = ConnectNamedPipe(hPipe, NULL) ? 
             TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 
     
          if (fConnected) 
          { 
             printf("Client connected, creating a processing thread.
    "); 
          
             // Create a thread for this client. 
             hThread = CreateThread( 
                NULL,              // no security attribute 
                0,                 // default stack size 
                InstanceThread,    // thread proc
                (LPVOID) hPipe,    // thread parameter 
                0,                 // not suspended 
                &dwThreadId);      // returns thread ID 
    
             if (hThread == NULL) 
             {
                _tprintf(TEXT("CreateThread failed, GLE=%d.
    "), GetLastError()); 
                return -1;
             }
             else CloseHandle(hThread); 
           } 
          else 
            // The client could not connect, so close the pipe. 
             CloseHandle(hPipe); 
       } 
    
       return 0; 
    } 
     
    DWORD WINAPI InstanceThread(LPVOID lpvParam)
    // This routine is a thread processing function to read from and reply to a client
    // via the open pipe connection passed from the main loop. Note this allows
    // the main loop to continue executing, potentially creating more threads of
    // of this procedure to run concurrently, depending on the number of incoming
    // client connections.
    { 
       HANDLE hHeap      = GetProcessHeap();
       TCHAR* pchRequest = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
       TCHAR* pchReply   = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
    
       DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; 
       BOOL fSuccess = FALSE;
       HANDLE hPipe  = NULL;
    
       // Do some extra error checking since the app will keep running even if this
       // thread fails.
    
       if (lpvParam == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL value in lpvParam.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
           if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
           return (DWORD)-1;
       }
    
       if (pchRequest == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL heap allocation.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
           return (DWORD)-1;
       }
    
       if (pchReply == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL heap allocation.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
           return (DWORD)-1;
       }
    
       // Print verbose messages. In production code, this should be for debugging only.
       printf("InstanceThread created, receiving and processing messages.
    ");
    
    // The thread's parameter is a handle to a pipe object instance. 
     
       hPipe = (HANDLE) lpvParam; 
    
    // Loop until done reading
       while (1) 
       { 
       // Read client requests from the pipe. This simplistic code only allows messages
       // up to BUFSIZE characters in length.
          fSuccess = ReadFile( 
             hPipe,        // handle to pipe 
             pchRequest,    // buffer to receive data 
             BUFSIZE*sizeof(TCHAR), // size of buffer 
             &cbBytesRead, // number of bytes read 
             NULL);        // not overlapped I/O 
    
          if (!fSuccess || cbBytesRead == 0)
          {   
              if (GetLastError() == ERROR_BROKEN_PIPE)
              {
                  _tprintf(TEXT("InstanceThread: client disconnected.
    "), GetLastError()); 
              }
              else
              {
                  _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.
    "), GetLastError()); 
              }
              break;
          }
        //处理你接收到的字符串
       // Process the incoming message.
          GetAnswerToRequest(pchRequest, pchReply, &cbReplyBytes); 
     
       // Write the reply to the pipe. 
          fSuccess = WriteFile( 
             hPipe,        // handle to pipe 
             pchReply,     // buffer to write from 
             cbReplyBytes, // number of bytes to write 
             &cbWritten,   // number of bytes written 
             NULL);        // not overlapped I/O 
    
          if (!fSuccess || cbReplyBytes != cbWritten)
          {   
              _tprintf(TEXT("InstanceThread WriteFile failed, GLE=%d.
    "), GetLastError()); 
              break;
          }
      }
    
    // Flush the pipe to allow the client to read the pipe's contents 
    // before disconnecting. Then disconnect the pipe, and close the 
    // handle to this pipe instance. 
     
       FlushFileBuffers(hPipe); 
       DisconnectNamedPipe(hPipe); 
       CloseHandle(hPipe); 
    
       HeapFree(hHeap, 0, pchRequest);
       HeapFree(hHeap, 0, pchReply);
    
       printf("InstanceThread exitting.
    ");
       return 1;
    }
    
    VOID GetAnswerToRequest( LPTSTR pchRequest, 
                             LPTSTR pchReply, 
                             LPDWORD pchBytes )
    // This routine is a simple function to print the client request to the console
    // and populate the reply buffer with a default data string. This is where you
    // would put the actual client request processing code that runs in the context
    // of an instance thread. Keep in mind the main thread will continue to wait for
    // and receive other client connections while the instance thread is working.
    {
        _tprintf( TEXT("Client Request String:"%s"
    "), pchRequest );
    
        // Check the outgoing message to make sure it's not too long for the buffer.
        if (FAILED(StringCchCopy( pchReply, BUFSIZE, TEXT("default answer from server") )))
        {
            *pchBytes = 0;
            pchReply[0] = 0;
            printf("StringCchCopy failed, no outgoing message.
    ");
            return;
        }
        *pchBytes = (lstrlen(pchReply)+1)*sizeof(TCHAR);
    }
    

     参考:

    -----------------------------------------------------------------------------

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx

    Multithreaded Pipe Server

     

    The following example is a multithreaded pipe server. It has a main thread with a loop that creates a pipe instance and waits for a pipe client to connect. When a pipe client connects, the pipe server creates a thread to service that client and then continues to execute the loop in the main thread. It is possible for a pipe client to connect successfully to the pipe instance in the interval between calls to the CreateNamedPipe and ConnectNamedPipe functions. If this happens, ConnectNamedPipe returns zero, and GetLastError returns ERROR_PIPE_CONNECTED.

    The thread created to service each pipe instance reads requests from the pipe and writes replies to the pipe until the pipe client closes its handle. When this happens, the thread flushes the pipe, disconnects, closes its pipe handle, and terminates. The main thread will run until an error occurs or the process is ended.

    This pipe server can be used with the pipe client described in Named Pipe Client.

     
    #include <windows.h> 
    #include <stdio.h> 
    #include <tchar.h>
    #include <strsafe.h>
    
    #define BUFSIZE 512
     
    DWORD WINAPI InstanceThread(LPVOID); 
    VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD); 
     
    int _tmain(VOID) 
    { 
       BOOL   fConnected = FALSE; 
       DWORD  dwThreadId = 0; 
       HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 
       LPTSTR lpszPipename = TEXT("\\.\pipe\mynamedpipe"); 
     
    // The main loop creates an instance of the named pipe and 
    // then waits for a client to connect to it. When the client 
    // connects, a thread is created to handle communications 
    // with that client, and this loop is free to wait for the
    // next client connect request. It is an infinite loop.
     
       for (;;) 
       { 
          _tprintf( TEXT("
    Pipe Server: Main thread awaiting client connection on %s
    "), lpszPipename);
          hPipe = CreateNamedPipe( 
              lpszPipename,             // pipe name 
              PIPE_ACCESS_DUPLEX,       // read/write access 
              PIPE_TYPE_MESSAGE |       // message type pipe 
              PIPE_READMODE_MESSAGE |   // message-read mode 
              PIPE_WAIT,                // blocking mode 
              PIPE_UNLIMITED_INSTANCES, // max. instances  
              BUFSIZE,                  // output buffer size 
              BUFSIZE,                  // input buffer size 
              0,                        // client time-out 
              NULL);                    // default security attribute 
    
          if (hPipe == INVALID_HANDLE_VALUE) 
          {
              _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.
    "), GetLastError()); 
              return -1;
          }
     
          // Wait for the client to connect; if it succeeds, 
          // the function returns a nonzero value. If the function
          // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 
     
          fConnected = ConnectNamedPipe(hPipe, NULL) ? 
             TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 
     
          if (fConnected) 
          { 
             printf("Client connected, creating a processing thread.
    "); 
          
             // Create a thread for this client. 
             hThread = CreateThread( 
                NULL,              // no security attribute 
                0,                 // default stack size 
                InstanceThread,    // thread proc
                (LPVOID) hPipe,    // thread parameter 
                0,                 // not suspended 
                &dwThreadId);      // returns thread ID 
    
             if (hThread == NULL) 
             {
                _tprintf(TEXT("CreateThread failed, GLE=%d.
    "), GetLastError()); 
                return -1;
             }
             else CloseHandle(hThread); 
           } 
          else 
            // The client could not connect, so close the pipe. 
             CloseHandle(hPipe); 
       } 
    
       return 0; 
    } 
     
    DWORD WINAPI InstanceThread(LPVOID lpvParam)
    // This routine is a thread processing function to read from and reply to a client
    // via the open pipe connection passed from the main loop. Note this allows
    // the main loop to continue executing, potentially creating more threads of
    // of this procedure to run concurrently, depending on the number of incoming
    // client connections.
    { 
       HANDLE hHeap      = GetProcessHeap();
       TCHAR* pchRequest = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
       TCHAR* pchReply   = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));
    
       DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; 
       BOOL fSuccess = FALSE;
       HANDLE hPipe  = NULL;
    
       // Do some extra error checking since the app will keep running even if this
       // thread fails.
    
       if (lpvParam == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL value in lpvParam.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
           if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
           return (DWORD)-1;
       }
    
       if (pchRequest == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL heap allocation.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
           return (DWORD)-1;
       }
    
       if (pchReply == NULL)
       {
           printf( "
    ERROR - Pipe Server Failure:
    ");
           printf( "   InstanceThread got an unexpected NULL heap allocation.
    ");
           printf( "   InstanceThread exitting.
    ");
           if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
           return (DWORD)-1;
       }
    
       // Print verbose messages. In production code, this should be for debugging only.
       printf("InstanceThread created, receiving and processing messages.
    ");
    
    // The thread's parameter is a handle to a pipe object instance. 
     
       hPipe = (HANDLE) lpvParam; 
    
    // Loop until done reading
       while (1) 
       { 
       // Read client requests from the pipe. This simplistic code only allows messages
       // up to BUFSIZE characters in length.
          fSuccess = ReadFile( 
             hPipe,        // handle to pipe 
             pchRequest,    // buffer to receive data 
             BUFSIZE*sizeof(TCHAR), // size of buffer 
             &cbBytesRead, // number of bytes read 
             NULL);        // not overlapped I/O 
    
          if (!fSuccess || cbBytesRead == 0)
          {   
              if (GetLastError() == ERROR_BROKEN_PIPE)
              {
                  _tprintf(TEXT("InstanceThread: client disconnected.
    "), GetLastError()); 
              }
              else
              {
                  _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.
    "), GetLastError()); 
              }
              break;
          }
    
       // Process the incoming message.
          GetAnswerToRequest(pchRequest, pchReply, &cbReplyBytes); 
     
       // Write the reply to the pipe. 
          fSuccess = WriteFile( 
             hPipe,        // handle to pipe 
             pchReply,     // buffer to write from 
             cbReplyBytes, // number of bytes to write 
             &cbWritten,   // number of bytes written 
             NULL);        // not overlapped I/O 
    
          if (!fSuccess || cbReplyBytes != cbWritten)
          {   
              _tprintf(TEXT("InstanceThread WriteFile failed, GLE=%d.
    "), GetLastError()); 
              break;
          }
      }
    
    // Flush the pipe to allow the client to read the pipe's contents 
    // before disconnecting. Then disconnect the pipe, and close the 
    // handle to this pipe instance. 
     
       FlushFileBuffers(hPipe); 
       DisconnectNamedPipe(hPipe); 
       CloseHandle(hPipe); 
    
       HeapFree(hHeap, 0, pchRequest);
       HeapFree(hHeap, 0, pchReply);
    
       printf("InstanceThread exitting.
    ");
       return 1;
    }
    
    VOID GetAnswerToRequest( LPTSTR pchRequest, 
                             LPTSTR pchReply, 
                             LPDWORD pchBytes )
    // This routine is a simple function to print the client request to the console
    // and populate the reply buffer with a default data string. This is where you
    // would put the actual client request processing code that runs in the context
    // of an instance thread. Keep in mind the main thread will continue to wait for
    // and receive other client connections while the instance thread is working.
    {
        _tprintf( TEXT("Client Request String:"%s"
    "), pchRequest );
    
        // Check the outgoing message to make sure it's not too long for the buffer.
        if (FAILED(StringCchCopy( pchReply, BUFSIZE, TEXT("default answer from server") )))
        {
            *pchBytes = 0;
            pchReply[0] = 0;
            printf("StringCchCopy failed, no outgoing message.
    ");
            return;
        }
        *pchBytes = (lstrlen(pchReply)+1)*sizeof(TCHAR);
    }
    
    http://www.cnblogs.com/wardensky/p/4175212.html

    C#命名管道通信

    
    

    C#命名管道通信

    最近项目中要用c#进程间通信,以前常见的方法包括RMI、发消息等。但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用。RMI又用的太多了,准备用管道通信来做消息通信。

    管道通信以前在大学学过,包括匿名管道和命名管道。匿名管道只能用在父子进程之间;命名管道可以用在两个进程甚至跨服务器通信。这里给出命名管道的示例。

    服务器端代码

        private static void WaitData()
        {
            using (NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("testpipe", PipeDirection.InOut, 1))
            {
                try
                {
                    pipeServer.WaitForConnection();
                    pipeServer.ReadMode = PipeTransmissionMode.Byte;
                    using (StreamReader sr = new StreamReader(pipeServer))
                    {
                        string con = sr.ReadToEnd();
                        Console.WriteLine(con);
                    }
                }
                catch (IOException e)
                {
                    throw e;
                }
            }
        }

    客户端代码

        private static void SendData()
        {
            try
            {
                using (NamedPipeClientStream pipeClient =
              new NamedPipeClientStream("localhost", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None))
                {
                    pipeClient.Connect();
                    using (StreamWriter sw = new StreamWriter(pipeClient))
                    {
                        sw.WriteLine("hahha");
                        sw.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
           
        }

    参考:

    如何:使用命名管道进行网络进程间通信

    C#中使用命名管道进行进程通信的实例

    进程间通信 - 命名管道实现

    下面是匿名管道的通信 来自 msdn

    Creating a Child Process with Redirected Input and Output

     

    The example in this topic demonstrates how to create a child process using the CreateProcess function 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 STARTUPINFO structure, which makes them the standard handles inherited by the child process.

    The parent process uses the opposite ends of these two pipes to write to the child process's input and read from the child process's output. As specified in the STARTUPINFO structure, these handles are also inheritable. However, these handles must not be inherited. Therefore, before creating the child process, the parent process uses the SetHandleInformation function to ensure that the write handle for the child process's standard input and the read handle for the child process's standard input cannot be inherited. For more information, see Pipes.

    The following is the code for the parent process. It takes a single command-line argument: the name of a text file.

     
    #include <windows.h> 
    #include <tchar.h>
    #include <stdio.h> 
    #include <strsafe.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;
     
    void CreateChildProcess(void); 
    void WriteToPipe(void); 
    void ReadFromPipe(void); 
    void ErrorExit(PTSTR); 
     
    int _tmain(int argc, TCHAR *argv[]) 
    { 
       SECURITY_ATTRIBUTES saAttr; 
     
       printf("
    ->Start of parent execution.
    ");
    
    // Set the bInheritHandle flag so pipe handles are inherited. 
     
       saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
       saAttr.bInheritHandle = TRUE; 
       saAttr.lpSecurityDescriptor = NULL; 
    
    // Create a pipe for the child process's STDOUT. 
     
       if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) 
          ErrorExit(TEXT("StdoutRd CreatePipe")); 
    
    // Ensure the read handle to the pipe for STDOUT is not inherited.
    
       if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
          ErrorExit(TEXT("Stdout SetHandleInformation")); 
    
    // Create a pipe for the child process's STDIN. 
     
       if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
          ErrorExit(TEXT("Stdin CreatePipe")); 
    
    // Ensure the write handle to the pipe for STDIN is not inherited. 
     
       if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
          ErrorExit(TEXT("Stdin SetHandleInformation")); 
     
    // Create the child process. 
       
       CreateChildProcess();
    
    // Get a handle to an input file for the parent. 
    // This example assumes a plain text file and uses string output to verify data flow. 
     
       if (argc == 1) 
          ErrorExit(TEXT("Please specify an input file.
    ")); 
    
       g_hInputFile = CreateFile(
           argv[1], 
           GENERIC_READ, 
           0, 
           NULL, 
           OPEN_EXISTING, 
           FILE_ATTRIBUTE_READONLY, 
           NULL); 
    
       if ( g_hInputFile == INVALID_HANDLE_VALUE ) 
          ErrorExit(TEXT("CreateFile")); 
     
    // Write to the pipe that is the standard input for a child process. 
    // Data is written to the pipe's buffers, so it is not necessary to wait
    // until the child process is running before writing data.
     
       WriteToPipe(); 
       printf( "
    ->Contents of %s written to child STDIN pipe.
    ", argv[1]);
     
    // Read from pipe that is the standard output for child process. 
     
       printf( "
    ->Contents of child process STDOUT:
    
    ", argv[1]);
       ReadFromPipe(); 
    
       printf("
    ->End of parent execution.
    ");
    
    // The remaining open handles are cleaned up when this process terminates. 
    // To avoid resource leaks in a larger application, close handles explicitly. 
    
       return 0; 
    } 
     
    void CreateChildProcess()
    // Create a child process that uses the previously created pipes for STDIN and STDOUT.
    { 
       TCHAR szCmdline[]=TEXT("child");
       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 ) 
          ErrorExit(TEXT("CreateProcess"));
       else 
       {
          // 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);
       }
    }
     
    void WriteToPipe(void) 
    
    // Read from a file and write its contents to the pipe for the child's STDIN.
    // Stop when there is no more data. 
    { 
       DWORD dwRead, dwWritten; 
       CHAR chBuf[BUFSIZE];
       BOOL bSuccess = FALSE;
     
       for (;;) 
       { 
          bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
          if ( ! bSuccess || dwRead == 0 ) break; 
          
          bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL);
          if ( ! bSuccess ) break; 
       } 
     
    // Close the pipe handle so the child process stops reading. 
     
       if ( ! CloseHandle(g_hChildStd_IN_Wr) ) 
          ErrorExit(TEXT("StdInWr CloseHandle")); 
    } 
     
    void ReadFromPipe(void) 
    
    // Read output from the child process's pipe for STDOUT
    // and write to the parent process's pipe for STDOUT. 
    // Stop when there is no more data. 
    { 
       DWORD dwRead, dwWritten; 
       CHAR chBuf[BUFSIZE]; 
       BOOL bSuccess = FALSE;
       HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    
       for (;;) 
       { 
          bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
          if( ! bSuccess || dwRead == 0 ) break; 
    
          bSuccess = WriteFile(hParentStdOut, chBuf, 
                               dwRead, &dwWritten, NULL);
          if (! bSuccess ) break; 
       } 
    } 
     
    void ErrorExit(PTSTR lpszFunction) 
    
    // Format a readable error message, display a message box, 
    // and exit from the application.
    { 
        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError(); 
    
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
    
        lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
            (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
        StringCchPrintf((LPTSTR)lpDisplayBuf, 
            LocalSize(lpDisplayBuf) / sizeof(TCHAR),
            TEXT("%s failed with error %d: %s"), 
            lpszFunction, dw, lpMsgBuf); 
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 
    
        LocalFree(lpMsgBuf);
        LocalFree(lpDisplayBuf);
        ExitProcess(1);
    }
    
    
    

    The following is the code for the child process. It uses the inherited handles for STDIN and STDOUT to access the pipe created by the parent. The parent process reads from its input file and writes the information to a pipe. The child receives text through the pipe using STDIN and writes to the pipe using STDOUT. The parent reads from the read end of the pipe and displays the information to its STDOUT.

     
    #include <windows.h>
    #include <stdio.h>
    
    #define BUFSIZE 4096 
     
    int main(void) 
    { 
       CHAR chBuf[BUFSIZE]; 
       DWORD dwRead, dwWritten; 
       HANDLE hStdin, hStdout; 
       BOOL bSuccess; 
     
       hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
       hStdin = GetStdHandle(STD_INPUT_HANDLE); 
       if ( 
           (hStdout == INVALID_HANDLE_VALUE) || 
           (hStdin == INVALID_HANDLE_VALUE) 
          ) 
          ExitProcess(1); 
     
       // Send something to this process's stdout using printf.
       printf("
     ** This is a message from the child process. ** 
    ");
    
       // This simple algorithm uses the existence of the pipes to control execution.
       // It relies on the pipe buffers to ensure that no data is lost.
       // Larger applications would use more advanced process control.
    
       for (;;) 
       { 
       // Read from standard input and stop on error or no data.
          bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL); 
          
          if (! bSuccess || dwRead == 0) 
             break; 
     
       // Write to standard output and stop on error.
          bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL); 
          
          if (! bSuccess) 
             break; 
       } 
       return 0;
    }
    
    
    
  • 相关阅读:
    gw经销商上传部分代码
    lib
    【转】sql server的随机函数newID()和RAND()
    【源码】仿qq记住登录信息
    关于ConfigurationManager类
    oracle 10 协议适配器错误解决办法
    配置对象数据源时,无法找到业务对象的解决办法
    private的由来,让能你很容易地区分private与protected的用法!
    大树扎根不稳,缘何不倒?
    Html服务器控件常用属性InnerHtml属性及InnerText属性的区别
  • 原文地址:https://www.cnblogs.com/zhishuai/p/7992061.html
Copyright © 2011-2022 走看看