【问题标题】:Create child process in VB6 that get automatically terminated when the program is terminated在 VB6 中创建在程序终止时自动终止的子进程
【发布时间】:2013-04-09 12:25:02
【问题描述】:

我想创建一个运行两个子进程的程序。现在,我希望当我的应用程序被任务管理器终止或崩溃时,它的两个子进程应该自动终止。我该怎么做?

【问题讨论】:

  • 如何创建和启动子进程?使用 Shell 函数、CreateProcess API、DCOM 或任何其他方法?
  • @Arvo 实际上我的编程正在启动一个服务,当我的程序终止时需要停止该服务。在这种情况下,只能使用 Shell 函数或 CreateProcess,我准备使用这些。
  • “服务”是指 Windows 服务吗?您将问题表述为与您的应用程序产生的子进程有关。

标签: vb6 watchdog


【解决方案1】:

在 Windows 中,您可以使用 Job Objects -- 最接近 Linux 中的进程组的东西。只需研究 API,它与 XP(可能是 SP3)及更高版本兼容。

您必须将您的 VB6 进程分配给一个作业,然后您生成的所有其他进程都隐含地成为该作业的一部分。

看看Performing equivalent of “Kill Process Tree” in c++ on windows

【讨论】:

  • 哇不错。学到了一些新东西。谢谢!
【解决方案2】:

让客户端使用 FindWindow API 检查主节点是否仍在运行

例如:启动计算器,运行以下示例项目,然后关闭计算器.. 关闭计算器后,此示例项目也将关闭

'1 form with:
'  1 timer: name=Timer1
Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub Form_Load()
  With Timer1
    .Interval = 100
    .Enabled = True
  End With 'Timer1
End Sub

Private Sub Timer1_Timer()
  Dim hwnd As Long
  hwnd = FindWindow(vbNullString, "Rekenmachine")
  If hwnd = 0 Then Unload Me
End Sub

(Rekenmachine是windows中计算器的荷兰语名称,请改用您自己的程序名称)

【讨论】:

  • 可能是,我没写清楚。但是,在我的问题中,情况是相反的。在您的示例中,我希望计算器在 VB6 程序终止时自动关闭。
  • 我认为他建议在您的子进程中使用此逻辑,假设它们也是您负责的 vb 代码。然后当你的主窗口关闭时,孩子们会认识到这一点并自行关闭。
  • 在你想关闭的窗口中使用这个,并将“Rekenmachine”替换为你想跟随状态的窗口的标题。我假设您可以访问要自动关闭的进程的源代码。
  • 如果您只能访问主进程的源代码,该主进程启动了您没有源代码的其他 2 个进程,那么如果不创建另一个监控进程,您将无法执行此操作。当你的主服务器崩溃时,它不能再做任何事情了,所以你需要另一个进程来使用上面的代码来监控主服务器的状态。然后它可以使用此线程中的答案之一终止其他进程:stackoverflow.com/q/1378604/1584106 .. 完成后,关闭自身
【解决方案3】:

如果我错了,请纠正我:您有一个应用程序启动了 2 个其他进程(您无权访问其中的源代码),并且您希望在您的应用程序结束时终止这 2 个进程?

这可以在您的应用程序启动一个额外的进程来监控您的应用程序的状态并负责关闭其他 2 个进程时完成

例如,一个粗略的监控应用程序可能存在 1 个模块:

Option Explicit

Public pstrArg() As String

Private Sub Main()
  pstrArg = Split(Command, " ")
  Load frmMonitor
End Sub

这个模块加载一个名为 frmMonitor 的表单,上面有一个计时器控件:

Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub Form_Load()
  With Timer1
    .Interval = 100
    .Enabled = True
  End With 'Timer1
End Sub

Private Sub Timer1_Timer()
  Dim intIndex As Integer
  If FindWindow(vbNullString, pstrArg(0)) = 0 Then
    For intIndex = 1 To UBound(pstrArg)
      TerminateProcess pstrArg(intIndex)
    Next intIndex
    End
  End If
End Sub

Private Sub TerminateProcess(strName As String)
  Dim Process As Object
  For Each Process In GetObject("winmgmts:").ExecQuery("Select Name from Win32_Process Where Name = '" & strName & "'")
    Process.Terminate
  Next
End Sub

确保监控应用程序的启动函数是 sub Main 以便您可以使用命令行参数调用它

您可以按如下方式进行测试: 将监控应用程序编译成 MonitorApp.exe 并将其放置在与一个名为 frmTest 的 1 个表单的现有测试项目相同的文件夹中:

'1 form with:
'  1 timer control: name=Timer1
'  1 command button : name=Command1

Option Explicit

Private Sub Command1_Click()
  Shell "calc.exe"
End Sub

Private Sub Form_Load()
  Shell App.Path & "\MonitorApp.exe frmTest calc.exe"
End Sub

每次单击命令按钮时都会启动一个计算器 当您关闭表单时,monitor 应用程序将关闭所有计算器,然后自行完成

【讨论】:

  • 没有其他不需要创建新应用程序的替代方案吗?
  • 我不这么认为:因为你也想监控你自己的应用程序的崩溃......如果你的应用程序崩溃了,那么你什么也做不了......或者你必须知道它可能在哪里崩溃,在这种情况下你可能会做点什么:)
猜你喜欢
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多