2016-06-14 131 views
0

我正在尝试使用命名管道将c#项目与C++项目连接,但C++项目未连接。C#C++命名管道连接

PS:.exe文件都在同一个文件

侧的问题:我不明白我的使用管道名称前的“\\。\管道\。”。它做了什么,它真的很困难?

这里是我的代码也许你能发现错误

C#服务器:

的Program.cs

static class Program 
{ 

    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     pipeHandler pipe = new pipeHandler(); 

     var proc = new Process(); 
     proc.StartInfo.FileName = "cplpltestpipes.exe"; 
     proc.Start(); 


     pipe.establishConnection(); 

     Application.Run(new Form1(pipe)); 
    } 
} 


public class pipeHandler 
{ 

    private StreamReader re; 
    private StreamWriter wr; 
    private NamedPipeServerStream pipeServer; 

    public void establishConnection() 
    { 
     pipeServer = new NamedPipeServerStream("myNamedPipe1"); 
     pipeServer.WaitForConnection(); 
     re = new StreamReader(pipeServer); 
     wr = new StreamWriter(pipeServer); 
    } 

    public void writePipe(string text) 
    { 
     wr.Write(text); 

    } 

    public string readPipe() 
    { 
     if(re.Peek()==-1) 
      System.Threading.Thread.Sleep(2000); 
     if (re.Peek() > -1) 
     { 
      string s; 
      s = re.ReadToEnd(); 
      return s; 
     } 
     else 
      return "fail"; 
    } 


} 

Form1.cs中:

public partial class Form1 : Form 
{ 
    pipeHandler pipePointer; 
    public Form1(pipeHandler pipe) 
    { 
     pipePointer=pipe; 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     pipePointer.writePipe(textBox1.Text); 
     textBox2.Text = pipePointer.readPipe(); 
    } 


} 

C++客户

#define chrSize 16 

int main() 
{ 
    TCHAR chr[chrSize]; 
    DWORD bytesRead; 



HANDLE pipeHandler; 
LPTSTR pipeName = TEXT("\\\\.\\pipe\\myNamedPipe1"); 


pipeHandler = CreateFile(
    pipeName, // pipe name 
    GENERIC_READ | // read and write access 
    GENERIC_WRITE, 
    0,    // no sharing 
    NULL,   // default security attributes 
    OPEN_EXISTING, // opens existing pipe 
    0,    // default attributes 
    NULL);   // no template file 

bool flag=false; 

while (!flag) 
{ 
    flag = ConnectNamedPipe(pipeHandler, NULL); 
    cout << "trying"; 
} 



ReadFile(
    pipeHandler, // pipe handle 
    chr, // buffer to receive reply 
    chrSize * sizeof(TCHAR), // size of buffer 
    &bytesRead, // number of bytes read 
    NULL); // not overlapped 

cout << chr; 


LPTSTR pipeMessage = TEXT("message receive"); 
DWORD bytesToWrite= (lstrlen(pipeMessage) + 1) * sizeof(TCHAR); 
DWORD cbWritten; 


WriteFile(
    pipeHandler,     // pipe handle 
    pipeMessage,    // message 
    bytesToWrite,    // message length 
    &cbWritten,    // bytes written 
    NULL);     // not overlapped 


CloseHandle(pipeHandler); 

}

运行程序只是给这个例外在C#

**************异常文本************ ** System.InvalidOperationException:管道尚未连接。 .... .... ....

,并在C++中只是不断印刷“试图”在控制台

+0

我不明白'“\\。\管\'任何地方在你的代码。 –

+0

它不存在,因为我现在不它做什么和它不会以任何方式工作 – Awesome

+0

有关管道名称的解释,请参见https://msdn.microsoft.com/en-us/library/windows/desktop/aa365783(v=vs.85).aspx。 –

回答

1

当你调用CreateFile如何的CreateFile知道用字符串myNamedPipe1代表的对象是一个管道?它知道这个名字的前缀是\\ServerName\pipe\

你的情况ServerName可以只是.,因为这是“本机”的快捷方式,如果你的代码切换到LPTSTR pipeName = TEXT("\\\\.\\pipe\\myNamedPipe1");如果没有其他问题,就应该开始工作。

因为NamedPipeServerStreamputs it there for you您不需要把它放在C#代码中。

编辑:寻找你的代码,你可能需要移动pipeServer = new NamedPipeServerStream("myNamedPipe1");pipeHandler构造,现在你的C++程序可能启动服务器的要求不断启动前,即使你有正确的名称可能仍然会得到错误。

EDIT2:ConnectNamedPipe是C++相当于pipeServer.WaitForConnection();,你不应该做的是,如果C++程序是客户端。你应该是好去读书,并尽快写,你有一个有效的句柄从CreateFile

EDIT3:这里是如何改写C#应用程序在启动C++应用程序

之前启动服务器了一个例子
static class Program 
{  
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     //The server now gets created here. 
     pipeHandler pipe = new pipeHandler();  

     var proc = new Process(); 
     proc.StartInfo.FileName = "cplpltestpipes.exe"; 
     proc.Start(); 

     //The server used to be created here. 
     pipe.EstablishConnection(); 

     Application.Run(new Form1(pipe)); 
    } 
} 


public class pipeHandler 
{  
    private StreamReader re; 
    private StreamWriter wr; 
    private NamedPipeServerStream pipeServer; 

    public pipeHandler() 
    { 
     //We now create the server in the constructor. 
     pipeServer = new NamedPipeServerStream("myNamedPipe1"); 
    } 

    public void establishConnection() 
    { 
     pipeServer.WaitForConnection(); 
     re = new StreamReader(pipeServer); 
     wr = new StreamWriter(pipeServer); 
    } 
... 
} 

然后在你的C++代码删除

while (!flag) 
{ 
    flag = ConnectNamedPipe(pipeHandler, NULL); 
    cout << "trying"; 
} 
+0

它没有更多的连接错误,谢谢!但是现在c#应用程序冻结等待响应,C++应用程序无法读取和响应。如果你觉得慷慨,你可以看看我的其他代码?先谢谢你! – Awesome

+0

'readPipe()'看起来超级干净。摆脱所有偷看的东西,只是读取数据。 Beond认为,使用调试器并找出停止的线路并提出一个新问题。 –