Как определить связь между приложением VB6 и файлом exe, созданным с помощью CreateObject () - PullRequest
2 голосов
/ 13 декабря 2010

Нам нужно выяснить, как служба может посмотреть на работающее приложение VB6 и / или его исполняемый DCOM-файл, и выяснить, какое приложение VB6 подходит к какому DCOM-файлу.Приложение VB6 и порожденный exe находятся на одном сервере.

У нас есть приложение VB6, которое порождает экземпляр Bartender (из Seagull Scientific) посредством вызова CreateObject ().На данном сервере у нас может быть десять или двадцать экземпляров нашего приложения, каждое из которых представляет собой портативного клиента RF-оружия на складе.95% или более из этих приложений VB6 будут иметь своего собственного бармена.

Из-за обстоятельств, не зависящих от нас, случайно, один из наших экземпляров VB6 будет убит, как если бы вы убили его с помощью диспетчера задач.Это оставляет Бармена еще живым и потребляющим ресурсы.После пятидесяти или около того убийств в течение нескольких часов или дней эти осиротевшие бармены становятся достаточным источником ресурсов, чтобы поставить сервер на колени.

Мы пытаемся разработать службу наблюдения для обнаружениякто из Барменов все еще подключен, так что этот новый сервис может убить осиротевших Барменов.Мы пытаемся сделать это без изменения нашего приложения VB6, но мы изменим наше приложение, если потребуется.

Ответы [ 3 ]

0 голосов
/ 20 декабря 2010

Это будет трудно, если не невозможно, сделать. Внешние COM-компоненты (то есть EXE-файлы ActiveX) всегда запускаются диспетчером управления службами COM, а не процессом, который вызывает CreateObject . Вот почему родительский процесс для ActiveX EXE svchost.exe .

Следовательно, между процессом, вызывающим CreateObject , и процессом, который создается, нет прямой связи между родителями и детьми. Только уровень удаленного вызова процедур (RPC), который фактически передает вызовы методов назад и вперед между двумя процессами, знает идентификаторы вовлеченных процессов, но механизм RPC специально разработан, чтобы быть прозрачным для подсистемы COM, и нет простой способ получить доступ к информации, которую я знаю.

Однако, есть довольно хакерский способ справиться с проблемой потерянного процесса, если вы хотите изменить приложение VB6:

  1. Служба монитора периодически прерывает все , на которых запущены Bartender EXE (один раз в день или, как это часто бывает, необходимо для предотвращения слишком сильного замедления работы сервера).

  2. Напишите DLL-оболочку для функциональности Bartender, и пусть ваш класс VB6 использует эту библиотеку-оболочку вместо непосредственного создания необработанных объектов Bartender. Эта библиотека будет содержать класс-оболочку, которая создает объект 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, и ваше приложение по-прежнему сможет работать должным образом. (в большинстве случаев), потому что, если вы убьете EXE-файл Bartender, который использовался запущенным экземпляром вашего приложения VB6, ваше приложение создаст новый экземпляр Bartender и продолжит работать в обычном режиме.

Это решение определенно не защищено от ошибок, и его может быть сложно реализовать, если вы используете много методов или у созданного вами экземпляра Bartender есть важное внутреннее состояние, которое может быть потеряно при создании нового экземпляра.

Когда дело доходит до этого, нет чистого способа обнаружить осиротевшие EXE-файлы ActiveX, если вы не управляете всеми участвующими приложениями (одно общее решение, когда вы делаете , контролируете ActiveX EXE должен заставить ActiveX EXE вызывать событие с параметром ByRef каждую секунду или около того и отключать его, если клиент не изменяет значение параметра).

0 голосов
/ 16 марта 2011

Мы решили, что клиент должен писать файл подсказок каждый раз, когда клиент создает бармена. Клиент записывает крошечный XML-файл в общую папку, которая говорит XML-эквивалент «Я - PID номер n. Между временем x и временем y я создал Bartender». Времена x и y являются временными метками, полученными непосредственно до и после вызова CreateObject. У нас будет служба мониторинга, которая отслеживает новых клиентов, новых барменов и файлы подсказок. Наблюдая за всем этим, мы думаем, что можем создать небольшие группы или ассоциации клиентов и связанных с ними барменов. В любой данной группе, когда все клиенты уйдут, любые оставшиеся бармены, которые были в этой группе, могут быть УБИТЫ!

0 голосов
/ 14 декабря 2010

Я думаю, что эта рутина , метко названная «Кто твой папочка», может пригодиться тебе.Он выясняет, кто породил процесс.Возможно, это не решит всю вашу проблему, но это только начало.

...