- PR -

C#で名前付きパイプでプロセス間通信を

1
投稿者投稿内容
Kazu
会議室デビュー日: 2005/05/12
投稿数: 4
投稿日時: 2005-05-12 12:30
はじめまして、C#をはじめて1年未満の初心者です

早速なのですが、
C#で以下のようなことを実現したいのですが、
どのようにコーディングしたらよいかわかりません。
どなたかご教示いただければ幸いです。

 @クライアント、サーバを用意
 Aクライアント側のPGから→サーバへ「名前付きパイプ」を使用しデータ(テキストファイル又はXMLファイル)の送信を行う。
 Bサーバではサービス等を使用しクライアント側からのデータの受信を待つ。
 Cデータを受信したらサーバ側のPGでデータを読込みその先の処理を行う。

書籍、Webを調べてもわかりません。
(一部[C++]で書かれたものは有ったのですがC++は全く知らないもので・・・)

今まで調べた中で、
「Win32 API」の「CreateFile」「WriteFile」「CreateNamedPipe」「ConnectNamedPipe」
を使用するみたいなのですが。
C#でそれらを使用するとした場合、
どのように使用すればよいのかそのあたりがよくわかりません。

特に、
[DllImport("kernel32")]を利用し
APIを宣言する過程で「引数の型」、「引数の値」
に何をセットすればよいか、そのあたりがよくわかりません。

うまく表現できずお手数をおかけしますが、
よろしくお願いいたします。

ちなみに参考にしたページは以下のWEBサイトです。
http://www.ipa.go.jp/security/awareness/vendor/programming/b08_02.html
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-05-12 14:40
こんにちは。

C#からWin32APIを呼び出すにはPInvoke(Platform Invocation Services)という仕組みで呼び出します。こちらが参考になるかな。

Win32 APIやDLL関数を呼び出すには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html

Win32 API呼び出しを手軽に記述するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/166pinvoke/pinvoke.html

パイプを扱うAPIを呼び出せば、多分いけると思います(C#でパイプを扱ったことが無いので絶対的なことはいえませんが)

ただ、目的とするものが、「パイプを使う」ではなく「プロセス間通信をしたい」というようなものであれば、.NETにはリモーティングというプロセス間通信を行う仕組みがあるので、C#でプロセス間通信をしたいのであれば、そちらを利用されることを薦めます。

Microsoft .NET リモーティング: 技術概要
http://www.microsoft.com/japan/msdn/net/general/hawkremoting.asp
(このページだけだと分かりにくいかも。。。リモーティング[Remoting]で情報を拾ってください)
Kazu
会議室デビュー日: 2005/05/12
投稿数: 4
投稿日時: 2005-05-12 16:16
nodera様
早速のご返答ありがとうございます。

1、「名前付きパイプ」について
  「名前付きパイプ」についてですが、教えていただいたリンク先等を参考に
   取りあえず以下のようにコーディングしてみたのですが(クライアント側)
  
  「CreateFile」(名前付きパイプへの接続)は以下のようにして、
取りあえずコンパイルも通り、結果として-1が帰ってきたのでOKかと思うのですが、

  「WriteFile」(メッセージの送信)でコンパイルエラーとなります。
  
  というよりも、引数の2番目にバッファ(送信内容)を入れたいのだが、
  どのように入れたらよいのかわからないのですがどのようにしたらよいのでしょうか?
  たとえば1例として、「"abc"」という文字列を送信したい場合の
コーディングのサンプル等を教えていただけないでしょうか?

C#   
================================================================================ //・「CreateFile」

[DllImport("kernel32")]
static extern IntPtr CreateFile(
string IpFileName, // ファイル名
UInt32 dwDesiredAccess, // アクセスモード
UInt32 dwShareMode, // 共有モード
//IntPtr IpSecurityAttributes, // セキュリティ記述子
UInt32 dwcreationDisposition, // 作成方法
UInt32 dwFlagsAndAttributes // ファイル属性
//IntPtr hTemplateFile // テンプレートファイルのハンドル
);

System.IntPtr hPipe = CreateFile("\\\\\\\\\\\\\\\\.\\\\\\\\pipe\\\\\\\\commandersvc",
unchecked((uint)0x40000000),
1, 3,
0x00000080);

//引数は「ファイル名」,
「GENERIC_WRITE」,
「FILE_SHARE_READ」,
「OPEN_EXISTING」,
「FILE_ATTRIBUTE_NORMAL」を選択

----------------------------------------------------------------------
//・「WriteFile」

[DllImport("Kernel32.dll", SetLastError=true, EntryPoint="WriteFile")]
static extern bool WriteFile(
IntPtr handle, // ファイルのハンドル
IntPtr buffer, // データバッファ
uint NumberOfBytesToWrite, // 書き込み対象のバイト数
out uint NumberOfBytesWritten, // 書き込んだバイト数
IntPtr overlapped // オーバーラップ構造体のバッファ
);

bool br = WriteFile (hPipe,
(IntPtr)data,
NumberOfBytesToWrite,
out NumberOfBytesWritten,
IntPtr.Zero
);
================================================================================

2、「リモーティング」について
  また、「リモーティング」については同時並行で検討することにしました。
  返答していただいたついでで申し訳ないのですが、
 「リモーティング」って非同期通信になるんでしょうか?
  クライアント側のPGにはサーバに送るデータを作る処理(一定間隔で行う)を、
  サーバ側のPGには受信したデータを処理する処理を抱えているため
  非同期で動かしたいのですが。

何分わからないため、うまく表現できず、お手数をおかけしますが
ご教示いただければ幸いです。

nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-05-12 18:22
こんにちは。

>というよりも、引数の2番目にバッファ(送信内容)を入れたいのだが、
>どのように入れたらよいのかわからないのですがどのようにしたらよいのでしょうか?

2番目の引数はバイトデータのポインタを渡さなければいけないと思われるの、定義をbyte[] bufferにして、"abc"を何らかの方法でbyte配列に直す必要があるかと。

ここでサンプルダウンロードできるようなので(メールアドレスの登録が必要)、参考にしてみたらいかがでしょうか。
http://www.codeproject.com/csharp/DotNetNamedPipesPart1.asp

>「リモーティング」って非同期通信になるんでしょうか?
delegateとBeginInvokeを利用すれば非同期通信も出来ます。

同期通信だったとしても、サーバー側の実装としては要求を受けたら処理を別スレッドに委譲して、受け側はすぐに要求側へ処理を戻せば、非同期で処理できるでしょう。
Kazu
会議室デビュー日: 2005/05/12
投稿数: 4
投稿日時: 2005-05-13 09:30
nodera様

早々のご返答ありがとうございます。

ご教示いただいた点を参考に再度、検討してみます。

渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-05-13 10:00
引用:

  「CreateFile」(名前付きパイプへの接続)は以下のようにして、
取りあえずコンパイルも通り、結果として-1が帰ってきたのでOKかと思うのですが、



全然ダメです。
CreateFile() に失敗しています。

-1 が「正常」の根拠は何ですか?

CreateFile() のヘルプの「戻り値」の欄に書いてある INVALID_HANDLE_VALUE の値が何であるか、きちんと調べましたか?

ちなみに、PInvoke の定義書くのをサボりたい人には

PINVOKE.NET
http://www.pinvoke.net/

がお勧めです。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
Kazu
会議室デビュー日: 2005/05/12
投稿数: 4
投稿日時: 2005-05-15 01:47
渋木宏明(ひどり)様

返答ありがとうございます。
以下のご指摘ありがとうございます。

私の思い違いだったようです。
私の勉強不足でした、
再度、確認して試して見ます。


1

スキルアップ/キャリアアップ(JOB@IT)