title: How do you send a named pipe string from umnanaged to managed code space?
body: <p>I appear to have a named pipes 101 issue. I have a very simple set up to connect a simplex named pipe transmitting from a C++ unmanaged app to a C# managed app. The pipe connects, but I cannot send a "message" through the pipe unless I close the handle which appears to flush the buffer and pass the message through. It's like the message is blocked. I have tried reversing the roles of client/server and invoking them with different Flag combinations without any luck. I can easily send messages in the other direction from C# managed to C++ unmanaged. Does anyone have any insight. Can any of you guys successfully send messages from C++ unmanaged to C# managed? I can find plenty of examples of intra amanged or unmanaged pipes but not inter managed to/from unamanged - just claims to be able to do it.</p>
  
  <p>In the listings, I have omitted much of the wrapper stuff for clarity. The key bits I believe that are relevant are the pipe connection/creation/read and write methods. Don't worry too much about blocking/threading here.</p>
  
  <p>C# Server side</p>
  
  <pre><code>    // This runs in its own thread and so it is OK to block
      private void ConnectToClient()
      {
          // This server will listen to the sending client
          if (m_InPipeStream == null)
          {
              m_InPipeStream =
                  new NamedPipeServerStream("TestPipe", PipeDirection.In, 1);
          }
  
          // Wait for client to connect to our server
          m_InPipeStream.WaitForConnection();
  
          // Verify client is running
          if (!m_InPipeStream.IsConnected)
          {
              return;
          }
  
          // Start listening for messages on the client stream
          if (m_InPipeStream != null &amp;&amp; m_InPipeStream.CanRead)
          {
              ReadThread = new Thread(new ParameterizedThreadStart(Read));
              ReadThread.Start(m_InPipeStream);
          }
      }
  
  
      // This runs in its own thread and so it is OK to block
      private void Read(object serverObj)
      {
          NamedPipeServerStream pipeStream = (NamedPipeServerStream)serverObj;
          using (StreamReader sr = new StreamReader(pipeStream))
          {
              while (true)
              {
                  string buffer = "" ;
                  try
                  {
                      // Blocks here until the handle is closed by the client-side!!
                      buffer = sr.ReadLine();   // &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;  Sticks here
                  }
                  catch
                  {
                      // Read error
                      break;
                  }
  
                  // Client has disconnected?
                  if (buffer == null || buffer.Length == 0)
                      break;
  
                  // Fire message received event if message is non-empty
                  if (MessageReceived != null &amp;&amp; buffer != "")
                  {
                      MessageReceived(buffer);
                  }
              }
          }
      }
  </code></pre>
  
  <p>C++ client side</p>
  
  <pre><code>    // Static - running in its own thread.
      DWORD CNamedPipe::ListenForServer(LPVOID arg)
      {
          // The calling app (this) is passed as the parameter
          CNamedPipe* app = (CNamedPipe*)arg;
  
          // Out-Pipe: connect as a client to a waiting server
          app-&gt;m_hOutPipeHandle =
          CreateFile("\\\\.\\pipe\\TestPipe",
                 GENERIC_WRITE,
                 0,
                 NULL,
                 OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL,
                 NULL);
          // Could not create handle
          if (app-&gt;m_hInPipeHandle == NULL ||
              app-&gt;m_hInPipeHandle == INVALID_HANDLE_VALUE)
          {
              return 1;
          }
  
          return 0;
      }
  
  
      // Sends a message to the server
      BOOL CNamedPipe::SendMessage(CString message)
      {
      DWORD dwSent;
  
          if (m_hOutPipeHandle == NULL ||
              m_hOutPipeHandle == INVALID_HANDLE_VALUE)
          {
              return FALSE;
          }
          else
          {
              BOOL bOK =
                  WriteFile(m_hOutPipeHandle,
                            message, message.GetLength()+1, &amp;dwSent, NULL);
              //FlushFileBuffers(m_hOutPipeHandle);             // &lt;&lt;&lt;&lt;&lt;&lt;&lt; Tried this
              return (!bOK || (message.GetLength()+1) != dwSent) ? FALSE : TRUE;
          }
      }
  
  
      // Somewhere in the Windows C++/MFC code...
      ...
      // This write is non-blocking. It just passes through having loaded the pipe.
      m_pNamedPipe-&gt;SendMessage("Hi de hi");
      ...
  </code></pre>