如何确定VB6应用程序与使用CreateObject()实例化的exe之间的关联

如何确定VB6应用程序与使用CreateObject()实例化的exe之间的关联,vb6,dcom,createobject,Vb6,Dcom,Createobject,我们需要弄清楚服务如何窥视正在运行的VB6应用程序和/或其DCOM生成的exe,并弄清楚哪个VB6应用程序与哪个DCOM exe相匹配。VB6应用程序和派生的exe都位于同一服务器上 我们有一个VB6应用程序,它通过CreateObject()调用生成一个调酒师实例(来自Seagull Scientific)。在给定的服务器上,我们可能有十个或二十个应用程序实例,每个实例代表仓库中的一个手持射频枪客户端。95%或更多的VB6应用程序将有自己的调酒师 由于我们无法控制的情况,我们的一个VB6实例将

我们需要弄清楚服务如何窥视正在运行的VB6应用程序和/或其DCOM生成的exe,并弄清楚哪个VB6应用程序与哪个DCOM exe相匹配。VB6应用程序和派生的exe都位于同一服务器上

我们有一个VB6应用程序,它通过CreateObject()调用生成一个调酒师实例(来自Seagull Scientific)。在给定的服务器上,我们可能有十个或二十个应用程序实例,每个实例代表仓库中的一个手持射频枪客户端。95%或更多的VB6应用程序将有自己的调酒师

由于我们无法控制的情况,我们的一个VB6实例将被随机终止,就像您使用任务管理器终止它一样。这使得它的调酒师仍然活着并消耗资源。在几小时或几天的时间里,大约有50人被杀,这些孤儿调酒师变成了资源猪,足以让服务员屈服


我们正在尝试开发一个观察服务,以检测哪些调酒师仍然连接,因此这项新服务可以杀死孤儿调酒师。我们正在尝试在不更改VB6应用程序的情况下实现这一点,但如果有必要,我们将修改我们的应用程序。

我认为这个名字很贴切,可能对您有用。它会找出是谁产生了这个过程。这可能不会解决你的整个问题,但这只是一个开始。

我认为这个名字很贴切,可能对你有用。它会找出是谁产生了这个过程。这可能无法解决您的整个问题,但这只是一个开始。

这将是一件很难做到的事情,如果不是不可能的话。进程外COM组件(即ActiveX EXE)始终由COM服务控制管理器启动,而不是由调用CreateObject的进程启动。这就是为什么ActiveX EXE的父进程是svchost.EXE

因此,调用CreateObject的进程与创建的进程之间没有直接的父子关系。只有在两个进程之间来回传递方法调用的远程过程调用(RPC)层才知道所涉及的进程的标识,但是RPC机制是专门设计为对COM子系统透明的,并且没有一种简单的方法可以访问我所知的此信息

但是,如果您愿意更改VB6应用程序,则有一种非常粗糙的方法来处理孤立进程问题:

  • 让您的监控服务定期终止所有正在运行的Bartender EXE(每天一次,或者无论多么频繁,都是防止服务器速度过慢所必需的)

  • 为调酒师功能编写包装器DLL,并让VB6类使用此包装器库,而不是直接实例化原始调酒师对象。该库将包含一个包装器类,该类创建一个调酒师对象,并具有委托给该对象的方法。每个包装器方法都应该捕获错误462(“远程服务器计算机不存在或不可用”),如果出现这种情况,请重新创建Bartender对象,然后重试该方法

  • 例如(我实际上没有看过酒保文档,所以这只是在演示这个想法):

    这里的想法是,由于您无法可靠地确定哪些调酒师进程仍然连接到VB6应用程序的实例,因此可以定期终止所有正在运行的调酒师进程,并且应用程序仍然能够正常运行(在大多数情况下),因为如果您杀死VB6应用程序的运行实例正在使用的Bartender EXE,应用程序将创建一个新的Bartender实例并继续正常运行

    这个解决方案绝对不是傻瓜式的,如果您使用了很多方法,或者您创建的酒保实例具有重要的内部状态,在创建新实例时可能会丢失这些状态,那么这个解决方案可能很难实现


    归根结底,如果不控制所有涉及的应用程序,就没有一种干净的方法来检测孤立的ActiveX EXE(当您控制ActiveX EXE时,一种常见的解决方案是让ActiveX EXE每隔一秒左右引发一个带有ByRef参数的事件,如果客户端不更改参数的值,则让它自行关闭)。

    这将是很难做到的,如果不是不可能做到的话。进程外COM组件(即ActiveX EXE)始终由COM服务控制管理器启动,而不是由调用CreateObject的进程启动。这就是ActiveX EXE的父进程为svchost.EXE的原因

    因此,调用CreateObject的进程与创建的进程之间没有直接的父子关系。只有远程过程调用(RPC)实际上在两个进程之间来回传递方法调用的层知道所涉及的进程的标识,但是RPC机制是专门设计为对COM子系统透明的,并且据我所知,没有一种简单的方法可以访问这些信息

    但是,如果您愿意更改VB6应用程序,则有一种非常粗糙的方法来处理孤立进程问题:

  • 让您的监控服务定期终止所有正在运行的Bartender EXE(每天一次,或者无论多么频繁,都是防止服务器速度过慢所必需的)

  • 为调酒师功能编写包装器DLL,并让VB6类使用此包装器库,而不是直接实例化原始调酒师对象。此库将包含一个创建调酒师对象的包装器类,该包装器类具有委托给此对象的方法。每个包装器方法应捕获错误462(“远程服务器计算机不存在或不可用”),如果出现这种情况,请重新创建调酒师对象,然后重新启动
    '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