2009-08-11 15 views
5

Vista/Windows2008/Windows7のデスクトップアプリケーションとWindowsサービスとの通信方法を教えてください。アプリケーションは小さな文字列をサービスに送り、文字列応答を返す必要があります。どちらもDelphi 2009で書かれています。(サンプルコードも提供してください)Delphi 2009:VistaのWindowsサービスとデスクトップアプリケーションの通信方法

+0

素晴らしいです!私は同じ質問をしましたが、私はもっと謙虚でもありましたが、私は答えの代わりに批判を受けました...--) – PSyLoCKe

答えて

6

移動方法はnamed pipesです。異なるIntegrity levelsの通信を調べる必要があります。

This article Vistaでこれを行う方法を調べます。これはC++で書かれていますが、基本的なWindows APIコールであるため、Delphiに十分速く変換する必要があります。

この件についてさらに検索したい場合、この通信はInter Process Communicationと呼ばれますが、より良い検索語はIPCです。

+1

これは本当ですか?私は、TCPサーバーとTCPクライアントの両方として機能するいくつかのWindowsサービスを行ってきました。彼らはすべて「ローカルシステム」として正常に動作します。私はいつもその制限がネットワークリソース(//マシン/リソース/ ...)にあると信じてきました。 –

+1

最初のアサーションは完全に偽です。私が今までに書いたすべてのWindowsサービスは、ある種のネットワーキングデーモンでした。ファンキーなアクセス許可が必要だった唯一の時間は、UIを表示できる必要があったということでした。 –

+0

はい、間違ったことを思い出しました。外部リソースへのネットワーク接続を作成することはできません。また、NetworkServiceとして実行する必要があります。私は最初の主張を削除した。 –

2

私はそれを試していませんが、名前付きパイプを使用できると思います。

3

今日はほぼ同じ質問であるExchange Data between two apps across PC on LANの回答を見てください。 TCPを介したローカル通信が標準です。私の回答では、「リモートプロシージャコール」タイプのインターフェイスを使用するソリューションがうまく機能します。私はRemObjects SDKをこの種のものに使用しており、後で望むならば、ネットワーク全体を制御するために簡単に拡張することができます。

これらの両方を使用すると、ほとんどのコードが「透過」で、ワイヤを介してデータを送信して結果を返すインターフェイスを呼び出すことができます。普通のやり方をプログラムして、ソケットなどの詳細を忘れることができます。

+1

サービスはネットワークを使用するために特別な権限を持っている必要はありませんそれはローカルでのみ聞いていますか? –

+0

@Robでは、サービスが実行されているアカウントによって異なります。 – Kevin

+0

システムアカウントまたはユーザーアカウントのいずれかを使用してRemObjectsを使用しても問題はありませんでした。この問題は、独立したTCP/IPソケットアクセスよりもドメインユーザーの権利に関連しています。 – mj2008

5

Indyを使用すると、アプリケーション間で比較的簡単にTCP接続を作成できます。特に、文字列メッセージを送信するだけでよい場合。クライアント(あなたのケースでデスクトップアプリケーション)の場合、それは基本的にサーバの場合

var 
    Client : TIdTCPClient; 
... 
Client.Host := 'localhost'; 
Client.Port := AnyFreePortNumber; 
Client.Connect; 
Client.IOHandler.Writeln (SomeString); 
Response := Client.Readln; 
... 
Client.Disconnect; 

です(あなたのケースでのサービスになります)

var 
    Server : TIdTCPServer; 
    Binding : TIdSocketHandle; 
... 
Server.DefaultPort := SameFreePortNumberAsInClient; 
Binding := Server.Bindings.Add; 
Binding.IP := '127.0.0.1';  
Binding.Port := Server.DefaultPort; 
Server.OnConnect := HandleConnection; 
Server.OnDisconnect := HandleDisconnection; 
Server.OnExecute := HandleCommunication; 
Server.Active := True; 

ちょうどHandleCommunicationメソッドを実装します。クライアントが何かを送ることを決めるときはいつでも呼び出されます。例:

procedure MyClass.HandleCommunication (AContext : TIdContext); 
var 
    Request : String; 
begin 
    Request := AContext.Connection.IOHandler.Readln; 
    if (Request = Command1) then 
    HandleCommand1 
    else if (Request = Command2) then 
    HandleCommand2 
    ... 
end; 

IIRCサービスは、唯一のグラフィカル・ユーザー・インターフェースを持っているか、ネットワークへのアクセスを持つことが許可されているので、あなたのサービスは(あなたがこのquestionを参照してください、とにかく避けるべきです)GUIを必要とする場合、これは問題になるかもしれません。私はこれがWindwos Vistaとそれ以降でどのように処理されるのかわかりません。

3

サービスユーザーをlocalsystemからnetworkserviceに変更してから、サービスがTCPIP fineを使用する必要があります。私は外部制御フックのためにTCPIPを使用するいくつかのサービスを持っています。サービスポートが構成可能であることを確認して、衝突を処理できるようにしてください。

私のコントロールインターフェイスのいくつかは、内部HTTPサーバーから提供されるXMLページに基づいています。これにより、そのマシン上のポートに到達可能なWebブラウザを使用して、サービスのステータスをリモートで確認することができます。他の方法よりもHTTPを使用する利点は、既存のネットワークハードウェアで作業する必要がある場合にうまく機能することです。

ローカルでのみ通信する場合は、名前付きパイプmail slots or a memory mapped fileが最適な方法です。

+0

TCPを使用するためにNetworkServiceアカウントを使用する必要はありません。 LocalSystemとLocalServiceのアカウントでもうまく動作します。 –

1

私は自分のサービスアプリケーションで、Simple IPCと呼ばれるソースコードを持つフリーウェアのコンポーネントセットを使用します。

検索torry.net。デスクトップアプリケーションと通信するとき、私のすべてのサービスアプリでうまくいきました。

ジョン