2017-05-02 8 views
3

特定のアクションが発生したときにC#アプリケーションに知らせるためにC++アプリケーションを取得しようとしています。私がこれをやろうとしているのは、名前付きパイプによるものです。名前付きパイプC#クライアントがC++サーバーに接続できません

私は、動作していると思われる名前付きパイプサーバーをC++アプリケーションにセットアップしました(名前付きパイプが作成されます - PipeListによって取得されたリストに表示されます)。それは失敗します:C#クライアントコードの最初の行は「パイプハンドルが設定されていません。あなたのPipeStream実装がInitializeHandleを呼び出しましたか?エラーが発生し、2行目で「パスへのアクセスが拒否されました」という例外がスローされます。

どこが間違っていますか?

C++ Serverコード

CString namedPipeName = "\\\\.\\pipe\\TitleChangePipe"; 

HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); 
if (pipe == INVALID_HANDLE_VALUE) { 
    MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR); 
    return -1; 
} 

char line[512]; DWORD numRead; 

while (true)//just keep doing this 
{ 
    numRead = 1; 
    while ((numRead < 10 || numRead > 511) && numRead > 0) 
    { 
     if (!ReadFile(pipe, line, 512, &numRead, NULL) || numRead < 1) {//Blocking call 
      CloseHandle(pipe);           //If something went wrong, reset pipe 
      pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL); 
      ConnectNamedPipe(pipe, NULL); 
      if (pipe == INVALID_HANDLE_VALUE) { 
       MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR); 
       return -1; } 
      numRead = 1; 
     } 
    } 
    line[numRead] = '\0'; //Terminate String 
} 

CloseHandle(pipe); 

C#クライアントコード

var client = new NamedPipeClientStream(".", "TitleChangePipe", PipeDirection.InOut); 
client.Connect(); 
var reader = new StreamReader(client); 
var writer = new StreamWriter(client); 

while (true) 
{ 
    var input = Console.ReadLine(); 
    if (String.IsNullOrEmpty(input)) 
     break; 
    writer.WriteLine(input); 
    writer.Flush(); 
    Console.WriteLine(reader.ReadLine()); 
} 

答えて

2

名前付きパイプの作成には、右のパラメータを持っていません。

最初にされますが、パイプに&書き込みを読んでもらいたいので、フラグを使用する:PIPE_ACCESS_DUPLEX

次に、ここでは同期モードでメッセージを送信しています。 PIPE_WAIT | PIPE_TYPE_MESSAGE

最後に、マシン上でこのパイプのインスタンスを1つだけ許可しています。明らかに少なくとも2つは必要です:クライアント用のサーバー用に1つ。あなたがそれを使用する前に、このパイプの接続に対して待機しなければならないサーバーでパイプを作成した後PIPE_UNLIMITED_INSTANCES

HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_DUPLEX, \ 
           PIPE_WAIT | PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, \ 
           1024, 1024, 120 * 1000, NULL); 

:私はちょうど無制限フラグを使用することになりhttps://msdn.microsoft.com/en-us/library/windows/desktop/aa365146(v=vs.85).aspx

+0

は、応答と説明をありがとうございました。私は 'CreateNamedPipe'のインスタンスを変更し、記述された方法で勧告された変数を使用するようにしました。私が理解しているように、それを使用する前にパイプ上の接続を待っている限り、それは 'ConnectNamedPipe'がするものです。それが言われても、私は「パスが拒否されました」という例外はもう出ないのですが、私はまだ「パイプハンドルが設定されていません。あなたのPipeStream実装がInitializeHandleを呼び出しましたか?クライアントコードの最初の行に表示されます。 – Claudiu

+1

はい、ConnectNamedPipeはループ内だけでなく、それを使用します。 '\\ pipe'接頭辞と混同する可能性があるので、パイプの名前をもう一度確認してください。私も同様のスレッドが見つかりました:http://stackoverflow.com/questions/10740479/two-way-c-to-c-sharp-communication-using-named-pipes。 ;] – Tezirg

+0

ありがとう!あなたが言及したように、パイプの作成の後、私はループの外でそれを使用していなければなりません。今働いている:) – Claudiu

関連する問題