2

サービスが実行中の VB6 アプリおよび/またはその DCOM によって生成された exe をどのように覗くことができるかを理解し、どの VB6 アプリがどの DCOM exe と連携するかを理解する必要があります。VB6 アプリと生成された exe は両方とも同じサーバー上にあります。

CreateObject() 呼び出しを介して Bartender (Seagull Scientific から) のインスタンスを生成する VB6 アプリがあります。特定のサーバーには、アプリのインスタンスが 10 から 20 ある場合があり、それぞれが倉庫内のハンドヘルド RF ガン クライアントを表します。これらの VB6 アプリの 95% 以上には独自の Bartender があります。

制御できない状況により、VB6 インスタンスの 1 つが、タスク マネージャーを使用して強制終了した場合と同様に、ランダムに強制終了されます。これにより、バーテンダーはまだ生きており、リソースを消費しています。数時間または数日の間に 50 人ほどが殺された後、これらの孤児になったバーテンダーは、サーバーを屈服させるのに十分なリソースの浪費になります。

どのバーテンダーがまだ接続されているかを検出するためのウォッチャー サービスを開発しようとしているので、この新しいサービスは孤立したバーテンダーを殺すことができます。VB6 アプリを変更せずにこれを達成しようとしていますが、必要に応じてアプリを変更します。

4

3 に答える 3

0

これを行うのは、不可能ではないにしても難しいでしょう。プロセス外の COM コンポーネント (つまり、ActiveX EXE) は、 CreateObjectを呼び出したプロセスではなく、常に COM サービス コントロール マネージャーによって開始されます。これが、ActiveX EXE の親プロセスがsvchost.exeである理由です。

したがって、 CreateObjectを呼び出すプロセスと作成されるプロセスの間に直接の親子関係はありません。2 つのプロセス間でメソッド呼び出しを実際にやり取りするリモート プロシージャ コール (RPC) 層のみが、関連するプロセスの ID を認識しますが、RPC メカニズムは COM サブシステムに対して透過的になるように特別に設計されており、私が知っているこの情報にアクセスする簡単な方法。

ただし、VB6 アプリケーションを変更する場合は、孤立したプロセスの問題を処理するかなりハックな方法があります。

  1. 監視サービスに、実行中のすべての Bartender EXE を定期的に終了させます (1 日に 1 回、またはサーバーの速度が低下しすぎるのを防ぐために頻繁に行う必要があります)。

  2. Bartender 機能のラッパー DLL を作成し、生の Bartender オブジェクトを直接インスタンス化する代わりに、VB6 クラスでこのラッパー ライブラリを使用します。このライブラリには、Bartender オブジェクトを作成し、このオブジェクトに委譲するメソッドを持つラッパー クラスが含まれます。各ラッパー メソッドは、エラー 462 (「リモート サーバー マシンが存在しないか、使用できません」) をキャッチし、これが発生した場合は Bartender オブジェクトを再作成してから、メソッドを再試行する必要があります。

例 (私は実際に Bartender のドキュメントを見ていないので、これは単にアイデアを示しているだけです):

'BartenderWrapper.cls

Private m_bartender As Object

Private Sub Class_Initialize()
   Set m_bartender = CreateObject("Bartender.Application")    
End Sub

Public Sub PrintLabel(Byval sLabelData As String)

    On Error Goto ErrorHandler

    m_bartender.PrintLabel sLabelData

    Exit Sub

ErrorHandler:

    If IsRpcError(Err) Then
       Set m_bartender = CreateObject("Bartender.Application")
       Resume
    End If

    Err.Raise Err.Number, Err.Source, Err.Description

End Sub

Private Function IsRpcError(Byval e As ErrObject) As Boolean
    IsRpcError = (e.Number = 462)
End Function

ここでの考え方は、どの Bartender プロセスがまだ VB6 アプリケーションのインスタンスに接続されているかを確実に判断できないため、実行中のすべての Bartender プロセスを定期的に強制終了しても、アプリケーションは引き続き適切に実行できる (ほとんどの場合) ということです。これは、VB6 アプリケーションの実行中のインスタンスで使用されていた Bartender EXE を強制終了すると、アプリケーションは新しい Bartender インスタンスを作成し、通常どおり実行し続けるためです。

このソリューションは絶対に確実というわけではなく、多くのメソッドを使用している場合や、作成した Bartender インスタンスに新しいインスタンスの作成時に失われる可能性のある重要な内部状態がある場合、実装が難しい場合があります。

結局のところ、関連するすべてのアプリケーションを制御しないと、孤立した ActiveX EXE を検出するきれいな方法はありません (ActiveX EXE を制御する場合の一般的な解決策の 1 つは、ActiveX EXE を発生させることです)。 1 秒ごとにByRefパラメータを持つイベントを実行し、クライアントがパラメータの値を変更しない場合はイベント自体をシャットダウンします)。

于 2010-12-20T04:28:02.100 に答える
0

クライアントが Bartender を作成するたびに、クライアントにヒント ファイルを作成させることにしました。クライアントは、「私は PID 番号 n です。時間 x と時間 y の間で、バーテンダーを作成しました」と同等の XML を示す小さな XML ファイルを共通フォルダーに書き込みます。時刻 x と y は、CreateObject 呼び出しの直前と直後に取得されたタイムスタンプです。新しいクライアント、新しいバーテンダー、ヒント ファイルを監視する監視サービスがあります。これらすべてを監視することで、クライアントと関連するバーテンダーの小さなグループまたは関連付けを作成できると考えています。どのグループでも、すべてのクライアントがいなくなると、そのグループに残っていたバーテンダーが殺される可能性があります。

于 2011-03-16T16:21:45.833 に答える
0

Who's Your Daddy という適切な名前のこのルーチンは、あなたに役立つかもしれないと思います。誰がプロセスを生成したかを特定します。おそらく問題全体が解決するわけではありませんが、それが始まりです。

于 2010-12-14T02:25:42.330 に答える