-
前回「その2」では「メイン処理をスレッドにしたもので行います」と記しましたが、実際のプログラム例を示します。
プログラムの手順としては以下の様になります。- OnStart ではイベントログに開始メッセージを登録し、メイン処理スレッドの生成を行う。
- OnStop ではイベントログに停止メッセージを登録し、メインスレッド停止依頼フラグONし、メイン処理スレッドの生成を行う。
- メイン処理スレッドでは停止依頼フラグがONになるまでループ処理を行う。ループ内では Sleep で待ちを入れる。
■サービスPG・メイン処理をスレッド化
Public Class TestService Protected Overrides Sub OnStart(ByVal args() As String) ' サービスを開始するコードをここに追加します。このメソッドによって、 ' サービスが正しく実行されるようになります Me.EventLog.WriteEntry("サービスを開始します。") 'メイン処理スレッドの生成を行う Me.mThreadMain = New Threading.Thread(New Threading.ThreadStart(AddressOf Me.MainProc)) Me.mThreadMain.Start() End Sub Protected Overrides Sub OnStop() ' サービスを停止するのに必要な終了処理を実行するコードをここに追加します。 Me.EventLog.WriteEntry("サービスを停止します。") 'メインスレッド停止依頼フラグON Me.mblnThreadStop = True 'メインスレッドの停止を待つ Me.mThreadMain.Join() End Sub ' スレッドクラス Private mThreadMain As Threading.Thread ' スレッド停止フラグ Private mblnThreadStop As Boolean = False ' メイン処理スレッド Private Sub MainProc() Me.EventLog.WriteEntry("MainProc...開始。") Try While mblnThreadStop = False ' ここに本来のサービス処理を書く ' 待ち時間を入れる(このプロセスがCPUを独占しない様に) Threading.Thread.Sleep(100) End While Catch ex As Exception ' エラー処理があればここに書く End Try Me.EventLog.WriteEntry("MainProc...停止。") End Sub End Classこのプログラムの重要な点は、サービスの「開始」が行われた時に、 メイン処理をスレッドとして起動を掛けて即座に「開始」処理から抜け出るところです。 こうするのは「開始」処理の中では時間の掛かる処理が実行できないからです。
また、メインスレッド内でも Sleep 関数での待ちを入れていますが、 これが無いとこのスレッドがCPU時間を独占することになりますので、必要になります。
しかし、まだこれではサービスプログラムの枠を作っただけで、実際に何も処理は起こりません。
サービスプログラムが何を行うのかが、決まっていないからですが、 上記のソース内の「ここに本来のサービス処理を書く」の部分に書いていくことになります。
さて、今回のサービスプログラムを実際に「開始」し、「停止」した場合のイベントログを見てみます。
「コントロールパネル」⇒「管理ツール」⇒「イベント ビューアー」で起動し、 実際にイベントログが登録されているかを見てみます。確かにログは登録されている様ですが、上から6件のログを一覧で見てみます。
ログの一覧を表示するには、Windowsの powershell を起動し Get-EventLog コマンドを使います。
それでは 「Windows + R」 で「ファイル名を指定して実行」を開き、 powershell を起動します。
(尚 Get-EventLog の詳しい説明はここでは行いません)
powershell 起動後、以下のコマンドをキー入力してログ一覧を行います。- Get-EventLog Application -Newest 6
ログを見ますと、期待した通りの結果が得られました。
次の記事ではメイン処理スレッドの実際の中身を組み込んでいきたいと思います。関連する記事
⇒サービスプログラムの作り方について・その1
⇒サービスプログラムの作り方について・その2
⇒サービスプログラムの作り方について・その4(メイン処理内で別のスレッドを呼出す)
おすすめ書籍
PR -
前回「その1」ではサービスの処理として何もしなかったのですが、今回は少しだけ処理を追加していきます。
タイマコントロールを追加し、タイマイベント処理の中で、Windowsのイベントログに時刻の出力を行います。
TestService.vb[デザイン] のフォームを開き、タイマコントロールを設置するのですが、 「ツールボックス」にはタイマコントロールが現れていないと思いますので、 「ツールボックス」のウインドウの上でマウス右クリックして「アイテムの選択」を実行します。 さらに「.NET Framework コンポーネント」の名前が Timer で、名前空間が System.Timers をチェックし「OK」を押下します。
System.Timers.Timer を TestService.vb[デザイン] へドラッグ&ドロップし、タイマコントロールを設置します。 Timer1 のプロパティで以下の設定にします。- Enabled:False
- Interval:10000 (10秒毎のタイマイベントの発生)
尚、ServiceBase の TestService のプロパティ「AutoLog」が「True」になっているのを確認して下さい。 デフォルトで「True」なのですが、Microsoftのサイトによりますと、以下の様に書かれています。既定では、すべての Windows サービス プロジェクトはアプリケーション イベント ログとやり取りして、 そこに情報および例外を書き込むことができます。
アプリケーションにこの機能が必要かどうかを指定するには、 AutoLog プロパティを使用します。
既定では、Windows サービス プロジェクト テンプレートで作成したサービスには、ログが有効にされます。
EventLog クラスの静的フォームを使用すると、 EventLog コンポーネントのインスタンスを作成したり、手動でソースを登録したりすることなく、ログにサービス情報を書き込むことができます。では今回のソースとしては以下の様になります。
OnStart ではイベントログに開始メッセージを登録し、タイマの開始を指示します。
OnStop ではイベントログに停止メッセージを登録し、タイマの停止を指示します。
タイマイベントの Timer1_Elapsed では現在時刻をイベントログに登録します。Public Class TestService Protected Overrides Sub OnStart(ByVal args() As String) ' サービスを開始するコードをここに追加します。このメソッドによって、 ' サービスが正しく実行されるようになります Me.EventLog.WriteEntry("サービスを開始します。") ' タイマの開始 Me.Timer1.Enabled = True Me.EventLog.WriteEntry("サービスを開始しました。") End Sub Protected Overrides Sub OnStop() ' サービスを停止するのに必要な終了処理を実行するコードをここに追加します。 Me.EventLog.WriteEntry("サービスを停止します。") ' タイマの停止 Me.Timer1.Enabled = False Me.EventLog.WriteEntry("サービスを停止しました。") End Sub ' タイマイベント処理 Private Sub Timer1_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) Handles Timer1.Elapsed Try 'この段階では特に行う処理が無いのでイベントログへの出力を行う Me.EventLog.WriteEntry("タイマイベント:" & Now.ToString("yyyy/MM/dd HH:mm:ss")) Catch ex As Exception End Try End Sub End Class特にどうといった処理ではないので簡単な処理です。
このサービスプログラムですが、何かイベントが起こるのをこのプログラムの裏?で待っているわけで、 今回はタイマコントロールによるイベントを受け付ける様になっています。
「コントロールパネル」⇒「管理ツール」⇒「イベント ビューアー」で起動し、 実際にイベントログが登録されているかを見てみます。イベントログに「タイマイベント:YYYY/MM/DD HH:mm:ss」が正しく登録されている様です。
尚、「AutoLog」が「True」の場合には、 OnStart OnStop などではシステムがイベントログにそれぞれのメッセージを登録するため、 本当は上記の「サービスを開始しました。」「サービスを停止しました。」の登録は必要ありません。
ところで、OnStart OnStop の処理は長時間実行可能なわけでは無く、すぐに終わらせる必要があります。 その為、OnStart の中ではタイマコントロールをEnable にして、すぐに処理を終わっています。
実際のところタイマコントロールでは面白くないので、別スレッドを起動して、スレッド側でメイン処理として行う方がいいと思います。 次の記事ではメイン処理をスレッドにしたもので行います。関連する記事
⇒サービスプログラムの作り方について・その1
⇒サービスプログラムの作り方について・その3(メイン処理をスレッド化)
⇒サービスプログラムの作り方について・その4(メイン処理内で別のスレッドを呼出す)
おすすめ書籍
-
サービスプログラムの作成を行うことがあったので、作成方法の最初の部分を記します。
サービスプログラムはフォームを持つプログラムとは全く性格が異なり、作成手順も異なりますので、 手順を追いながら作成していきます。 尚、今回の作業を行うには、Windowsの管理者権限でログインしておいてください。
先ず、VisualStudioを起動し、新しいプロジェクトの作成を行います。 「新しいプロジェクト」ウインドウが表示されたら、テンプレートの中のVisualBasicを選択し、更に Windowsサービス を選択すると以下の様な表示なります。
「名前」が「WindowsServices1」となっているのを、仮に「TestService」に変更し、「OK」ボタンを押下します。
尚、画面はプロジェクト名を「TestService」と変更し、更に「TestService.vb[デザイン]」のプロパティで、「ServiceName」も「TestService」に全て変更しました。
ここをクリックするとコードビューに切り替わります。のリンクをクリックします。 すると、Service1.vb の内容が以下の様に表示されます。
ソースとしては以下の様になります。
Public Class TestService Protected Overrides Sub OnStart(ByVal args() As String) ' サービスを開始するコードをここに追加します。このメソッドによって、 ' サービスが正しく実行されるようになります End Sub Protected Overrides Sub OnStop() ' サービスを停止するのに必要な終了処理を実行するコードをここに追加します。 End Sub End ClassOnStart プロシージャと OnStop プロシージャのサービスへの機能追加を行い、再定義する他のすべてのメソッドを上書きします。
OnStart プロシージャは、「コントロールパネル」⇒「管理ツール」⇒「サービス」で起動される、画面の中で、各サービスでの「開始」操作に対応する処理を記述します。 また、OnStop プロシージャは、各サービスでの「停止」操作に対応する処理を記述します。
最初のテストなので、このままの状態でサービスを作成し、インストール行います。
「TestService.vb[デザイン]」を表示し、デザイン上で右クリックでメニューを表示させて、「インストーラーの追加」をクリックします.インストーラーのコントロールがプロジェクトに追加されて、以下の様な表示なります.
[ProjectInstaller] の [デザイン] ビューで、[ServiceInstaller1] を選択します。
[プロパティ] ウィンドウで、ServiceName プロパティが TestService に設定されていることを確認します。
「ソリューション エクスプローラー」の「ソリューション'TestService'」を選択し、VisualSutudioのメニューの「ビルド」⇒「ソリューションのビルド」を選択し、ビルドを行います.尚、ここでひとつ忘れていたのですが、「TestService」プロパティ設定で、スタートアップオブジェクトを「TestService」に設定しておきます.
では、作成されたサービスを実際に登録してみます。 登録方法は、Windows の [スタート] メニューまたは [スタート] 画面で、[Visual Studio]⇒[Visual Studio ツール]⇒[開発者コマンド プロンプト] の順に選択します。
Visual Studio コマンド プロンプトが表示されますので、インストールする場合は以下のコマンドを入力します。- installutil C:\TestService\TestService\bin\Debug\TestService.exe
アンインストールする場合は以下のコマンドを入力します。
- installutil /u C:\TestService\TestService\bin\Debug\TestService.exe
インストールコマンドを実行すると以下の様に、ログイン時のユーザー名とパスワードを聞いてきますので、 それぞれを入力して作業を進めます。
尚、ユーザー名の注意ですが、ログインしている私のマシンのAdmin属性のユーザを設定したのですが、ユーザ名の先頭に「.\」(ドット¥)が必要でした。インストールが完了すれば以下の表示になります。
これでサービスに登録が終わりましたので、「コントロールパネル」⇒「管理ツール」⇒「サービス」を起動します。 サービスの一覧の中に「TestService」があると思いますので、サービスの「開始」を行います。以下の様に、サービスの状態が「開始」になります。
サービスを止めるには「停止」を指定します。
アンインストールを実際に行った様子を以下に示します。結果、サービス一覧から「TestService」が削除されました。
今回はサービスプログラムの生成と登録までを行っただけで、実際に何かの処理を行うわけではありません。
今後は、何かの処理を行う部分を組み込んで、サービスプログラムについて考察していきたいと思います。関連する記事
⇒サービスプログラムの作り方について・その2
⇒サービスプログラムの作り方について・その3(メイン処理をスレッド化)
⇒サービスプログラムの作り方について・その4(メイン処理内で別のスレッドを呼出す)
おすすめ書籍
-
前回投稿した以下の記事ですが、プロセス間通信の方法としてRemoting の IPCを使用していました。
⇒Remoting の IPC を使ったプロセス間通信について
今回は、HTTPチャネルを介してのプロセス間通信に変更してみます。 前回同様、1個のソリューショの中に以下の3個のプロジェクトを設置します。- クライアントとサーバーで共有するクラスDLL
- サーバープロセスの実行PG(EXE)
- クライアントプロセスの実行PG(EXE)
先ず、プロセス間通信の準備として、クライアントとサーバーで共有するクラスの宣言ですがこれは前回と全く同じものです。クライアントとサーバーで共有するクラス
Public Class ServiceClass Inherits MarshalByRefObject 'クライアントから呼び出しを受け、イベントを発生させる Public Sub RaiseServerEvent(ByVal message As String) 'イベントを発生させる RaiseEvent RaiseClientEvent(message) End Sub Public Event RaiseClientEvent(ByVal messsage As String) End Classプロジェクトの定義は以下の様になります。
次に、サーバープロセスPGのプロジェクトを生成します。
1個のフォーム frmIpcServer をプロジェクトに追加し、そのフォーム上に1個のボタンとリッチエディットBOXを設置します。
フォームの静的変数として上記で説明した共有クラス(ServiceClass)の生成を行います。 また、ServiceClass から raise されるイベントの処理として、リッチエディットBOXに受信したメッセージを表示する為に、 デリゲート処理を宣言しています。
ボタンの押下によりHTTPの受信開始を行うのですが、以下の様な手順で行います。- HttpChannelによりHTTPチャネルを用意し、ChannelServices.RegisterChannel でチャネルを登録
- RemotingServices.Marshal により共有クラスの参照許可
- httpChannel.StartListening によりHTTPの受信を開始
サーバープロセスPG
Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Http Imports IpcService Public Class frmIpcServer 'IPC用クラスの生成 Private WithEvents IpcServiceClass As New IpcService.ServiceClass '受信回数 Private mintRcv As Integer = 0 '別プロセスからのメッセージを処理するためデリゲートを利用 Delegate Sub SetRichTextBox1Delegate(ByVal Value As String) Private RichTextBox1Delegate As New SetRichTextBox1Delegate(AddressOf AppendTextRichTextBox1) 'リッチテキストボックスにメッセージを表示する Private Sub AppendTextRichTextBox1(ByVal message As String) RichTextBox1.AppendText(message) End Sub '受信準備 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'HTTPチャネルを用意(ポートは8080を利用) Dim httpChannel = New HttpChannel(8080) ChannelServices.RegisterChannel(httpChannel, False) '「IpcServiceClass」を「ipcsample」で参照できるように設定 Dim ref As ObjRef = RemotingServices.Marshal(IpcServiceClass, "ipcsample") 'HTTP受信準備 httpChannel.StartListening(Nothing) RichTextBox1.AppendText("HTTP channel is ready to receive." & vbNewLine) End Sub 'IPC用クラスのイベント処理 Private Sub IpcServiceClass_RaiseClientEvent(ByVal message As String) Handles IpcServiceClass.RaiseClientEvent 'このイベント処理は、別プロセスのServiceClassからRaiseされるので、 'このフォームのコントロールにアクセスするにはデリゲート処理を行う '(クライアントから受信したメッセージを処理) mintRcv += 1 Me.Invoke(RichTextBox1Delegate, New Object() {mintRcv.ToString & ":" & message & vbNewLine}) End Sub End Class尚、このプロジェクトの参照設定で以下のものを追加します。
- System.Runtime.Remoting
- IpcService
最後に、クライアントプロセスPGのプロジェクトを生成します。
1個のフォーム frmIpcClient をプロジェクトに追加し、そのフォーム上に1個のボタンとディットBOXを設置します。
フォームロード時に ChannelServices.RegisterChannel でHTTPチャネルの用意を行い、 RemotingConfiguration.RegisterWellKnownClientType でリモートサーバへの接続準備を行います。
ボタン押下時に IPC用クラスの生成を行い、そのクラスのイベント発生メソッドを実行し、メッセージ送信処理を行います。
尚、このプロジェクトの参照設定もサーバープロセスPGと同様です。クライアントプロセスPG
Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Http Imports IpcService Public Class frmIpcClient 'IPC準備 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'HTTPチャネルを用意する Dim channel As New HttpChannel(0) ChannelServices.RegisterChannel(channel, False) 'リモートサーバへの接続準備 RemotingConfiguration.RegisterWellKnownClientType(GetType(ServiceClass), "http://localhost:8080/ipcsample") End Sub 'メッセージを送信する Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Try 'IPC用クラスの生成 Dim IpcServiceClass As ServiceClass = New ServiceClass() 'サーバへの通知(引数には、送信したいメッセージを指定) IpcServiceClass.RaiseServerEvent("Message From Client=>" & Me.TextBox1.Text) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Classこのソリューションをデバッグ実行するために、ソリューションのプロパティを以下の図の様に設定します。
このソリューションをデバッグ実行すると以下の様になります。
サーバーPGの起動後、「Start HTTP Channel」ボタンを押下して HTTP 受信の準備を行います。 その後、クライアントPGのボタンを押下するごとに、サーバーPGにメッセージが表示されていきます。
関連する記事
⇒Remoting の IPC を使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)
-
同一PC上でプロセス(EXE)間で通信を行いたいことはよくあります。 例えば、1個のPGを何か受信専用として動作させておいて、別のPGではメインの処理を行いながら、たまに受信データの処理を行うなどの要求が出てきたりします。 別EXE同士でやり取りを行う場合には以下の様な方法があると思います。
- WindowsAPIのメッセージ通信
- WindowsAPIのPIPEでの通信
- WindowsAPIのファイルマッピングでの通信
- 通常のファイルを使った通信
- 遅くてOKならば、データベースを介した通信
尚、今回は勉強もかねて Remoting の IPC を使って、クライアントプロセス(EXE)からサーバープロセス(EXE)にメッセージを送信することをやってみます。
今回の例では、1個のソリューションの中に以下の3個のプロジェクトを生成します。- クライアントとサーバーで共有するクラスDLL
- サーバープロセスの実行PG(EXE)
- クライアントプロセスの実行PG(EXE)
先ず、プロセス間通信の準備として、クライアントとサーバーで共有するクラスの生成を行います。
以下のソースを見て下さい。MarshalByRefObject をクラスを継承したクラス ServiceClass を宣言しています。
内容的には多くのことをするわけでは無く、クライアントから呼出されるであろうメソッドで、 文字列データを引数としてイベントを raise しています。
このプロジェクトは IpcService と命名し、クラスライブラリ(DLL)としてビルドしておきます。
(後からこのDLLを、サーバープロセス及びクライアントプロセスのプロジェクトで参照設定します。)クライアントとサーバーで共有するクラス
Public Class ServiceClass Inherits MarshalByRefObject 'クライアントから呼び出しを受け、イベントを発生させる Public Sub RaiseServerEvent(ByVal message As String) 'イベントを発生させる RaiseEvent RaiseClientEvent(message) End Sub Public Event RaiseClientEvent(ByVal messsage As String) End Classプロジェクトの定義は以下の様になります。
次に、サーバープロセスPGのプロジェクトを生成します。
1個のフォーム frmIpcServer をプロジェクトに追加し、そのフォーム上に1個のボタンとリッチエディットBOXを設置します。
フォームの静的変数として上記で説明した共有クラス(ServiceClass)の生成を行います。 また、ServiceClass から raise されるイベントの処理として、リッチエディットBOXに受信したメッセージを表示する為に、 デリゲート処理を宣言しています。
ボタンの押下によりIPCの受信開始を行うのですが、以下の様な手順で行います。- IpcServerChannel によりIPCチャネルを用意し、ChannelServices.RegisterChannel でチャネルを登録
- RemotingConfiguration.RegisterWellKnownServiceType でサービスのタイプを宣言
- RemotingServices.Marshal により共有クラスの参照許可
- IpcChannel.StartListening によりIPCの受信を開始
サーバープロセスPG
Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Ipc Imports IpcService Public Class frmIpcServer 'IPC用クラスの生成 Private WithEvents IpcServiceClass As New IpcService.ServiceClass '受信回数 Private mintRcv As Integer = 0 '別プロセスからのメッセージを処理するためデリゲートを利用 Delegate Sub SetRichTextBox1Delegate(ByVal Value As String) Private RichTextBox1Delegate As New SetRichTextBox1Delegate(AddressOf AppendTextRichTextBox1) 'リッチテキストボックスにメッセージを表示する Private Sub AppendTextRichTextBox1(ByVal message As String) RichTextBox1.AppendText(message) End Sub 'IPC受信開始 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'IPCチャネルを用意 Dim IpcChannel As New IpcServerChannel("ipcPort") ChannelServices.RegisterChannel(IpcChannel, False) Dim strSClassName As String = GetType(ServiceClass).Name RemotingConfiguration.RegisterWellKnownServiceType(GetType(ServiceClass), strSClassName, WellKnownObjectMode.SingleCall) '「ServiceClass」を参照できるように設定 Dim ref As ObjRef = RemotingServices.Marshal(IpcServiceClass, strSClassName) 'IPC受信準備 IpcChannel.StartListening(Nothing) RichTextBox1.AppendText("IPC channel is ready to receive." & vbNewLine) End Sub 'IPC用クラスのイベント処理 Private Sub IpcServiceClass_RaiseClientEvent(ByVal message As String) Handles IpcServiceClass.RaiseClientEvent 'このイベント処理は、別プロセスのServiceClassからRaiseされるので、 'このフォームのコントロールにアクセスするにはデリゲート処理を行う '(クライアントから受信したメッセージを処理) mintRcv += 1 Me.Invoke(RichTextBox1Delegate, New Object() {mintRcv.ToString & ":" & message & vbNewLine}) End Sub End Class尚、このプロジェクトの参照設定で以下のものを追加します。
- System.Runtime.Remoting
- IpcService
最後に、クライアントプロセスPGのプロジェクトを生成します。
1個のフォーム frmIpcClient をプロジェクトに追加し、そのフォーム上に1個のボタンとディットBOXを設置します。
フォームロード時に ChannelServices.RegisterChannel でIPCチャネルの用意を行います。
ボタン押下時にメッセージ送信処理を行うのですが以下の様な手順で行います。- リモートIPCオブジェクトの URL を定義して Activator.GetObject 参照を取得
- その参照を共有クラスのオブジェクト変数に代入
- 共有参照クラスのイベント生成メソッド呼び出し
このプロジェクトの参照設定もサーバープロセスPGと同様です。
クライアントプロセスPG
Imports System.Runtime.Remoting Imports System.Runtime.Remoting.Channels Imports System.Runtime.Remoting.Channels.Ipc Imports IpcService Public Class frmIpcClient 'IPC準備 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'IPCチャネルを用意する Dim ipcChannel As New IpcClientChannel ChannelServices.RegisterChannel(ipcChannel, False) End Sub 'メッセージを送信する Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Try '既存のリモートIPCオブジェクトへの参照を取得する Dim strURL As String = "ipc://ipcPort/" + GetType(ServiceClass).Name Dim objRemote As Object = Activator.GetObject(GetType(ServiceClass), strURL) 'サーバとの共通クラスの参照(ServiceClass) Dim objServiceClass As ServiceClass = CType(objRemote, ServiceClass) '共有参照クラスのイベント生成メソッド呼び出し objServiceClass.RaiseServerEvent("Message From Client=>" & Me.TextBox1.Text) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Classこのソリューションをデバッグ実行するために、ソリューションのプロパティを以下の図の様に設定します。
このソリューションをデバッグ実行すると以下の様になります。
サーバーPGの起動後、「Start IPC Channel」ボタンを押下して IPC 受信の準備を行います。 その後、クライアントPGのボタンを押下するごとに、サーバーPGにメッセージが表示されていきます。
今回のPGはまだまだ不備な点が多いので実用には供しないですが、ご参考になればと思います。
関連する記事
⇒Remoting の IPC を使ったプロセス間通信についてその2(HTTPチャネル)
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)