【问题标题】:Can I create a child process using WMI VB scripting?我可以使用 WMI VB 脚本创建子进程吗?
【发布时间】:2008-12-05 15:24:39
【问题描述】:

使用 WMI VB 脚本,我想创建/附加多个子进程到父进程,例如资源管理器进程。

当一个应用通过点击启动时,它成为资源管理器进程的子进程。 Windows 启动时加载的所有应用程序也是如此。

如果您使用任务管理器中的“结束进程树”上下文菜单选项终止资源管理器进程,它也会终止资源管理器进程的所有子进程(一种无需重新启动即可清理内存的快速、蛮力方法)。

我有两个脚本 - 一个杀死一堆特定进程,另一个重新启动这些进程。

我的脚本中的大多数进程/应用程序都是在启动时加载的,因此它们是资源管理器进程的子进程。当我杀死资源管理器进程树时,所有这些进程都会死掉,如前所述。

当我使用脚本重新启动这些应用程序时,它们不再是资源管理器进程的子进程。当我杀死资源管理器进程树时,脚本启动的应用程序不会死。

现在,我知道我可以使用脚本单独杀死每个进程。但是在脚本中直接终止资源管理器进程树而不需要指定我要终止的单个应用程序会很好。

因此,如果我有一个脚本可以将我的应用程序作为资源管理器进程的子进程启动,那么我的另一个脚本只需终止资源管理器进程树即可。

我有一个脚本可以做到这一点。它循环并杀死资源管理器进程的所有子进程。但是,它仅适用于在启动时加载或被点击的应用程序。

此外,通过阻止这些应用程序在启动时加载,Windows 加载速度要快得多。稍后,我会在需要时单击脚本图标来加载我的应用程序。

这就是为什么我想创建一个脚本,它可以将应用程序作为资源管理器进程的子进程启动。

一个有趣的旁注:我必须推迟杀死任何命令/控制台进程,否则脚本可能会在获取其余进程之前杀死自己。

有什么想法可以做到这一点吗?

下面是我失败的代码。

Option Explicit
dim wmi, rootProcessName, rootProcess, objStartup, objConfig, objProcess, strComputer, dropbox, itunes, skype
strComputer = "."

dropbox="C:\Program Files\Dropbox\Dropbox.exe"
itunes="C:\Program Files\iTunes\iTunes.exe"
skype="C:\Program Files\Skype\Phone\Skype.exe"

Const NORMAL = 32
Set wmi = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objStartup =  wmi.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.PriorityClass = NORMAL

rootProcessName = "'explorer.exe'"
set rootProcess = wmi.ExecQuery("Select * from Win32_Process Where Name = " & rootProcessName )
For Each objProcess in rootProcess
    objProcess.Create dropbox, null, objConfig
    objProcess.Create itunes, null, objConfig
    objProcess.Create skype, null, objConfig
Next

WScript.Quit

【问题讨论】:

标签: vbscript process wmi


【解决方案1】:

窗口的进程会跟踪创建它的进程 ID,这就是管理关系的方式。要获得您想要的,您要么必须更改存储在子进程中的父 PID,要么将代码注入您想要成为父进程的进程并让它创建新的子进程。这些都不是真正可行的。

真正的解决方案是使用Job Objects,这样您就可以同时终止与作业相关的所有进程。但是你必须迁移出 vbscript。

【讨论】:

    【解决方案2】:

    在跟踪通过 CreateObject 实例化的事物的进程时,从 VBScript 启动应用程序有一个严重的缺点:根据对象的类型,应用程序的进程可能不会成为调用进程的子进程。相反,它将在 svchost.exe 进程下启动。

    假设我们正在使用 C/C++ 并希望从 VB 脚本启动 Excel。在 C/C++ 中,我们可能会执行以下操作:

    1. 调用 CreateJobObject()
    2. 创建要调用 .VBS 脚本的挂起进程
    3. 使用 AssignProcessToJobObject() 将创建的进程添加到作业中
    4. 调用 ResumeThread() 启动挂起的进程

    鉴于以上情况,大致如下:

    1. 创建的进程 P 开始作为作业 J 的成员运行。
    2. P 使用脚本宿主 H(cscript 或 wscript.exe)启动 VBS 文件
    3. H 按预期作为 P 的子节点运行
    4. H 执行 CreateObject("Excel.Application") 启动 Excel 作为服务
    5. 因此,Excel 成为服务宿主进程的子进程,不是 P
    6. 此进程 (svchost.exe -k DcomLaunch) 将 DLL 分组以执行 DCOM
    7. 脚本完成,H 终止
    8. E 继续前进,但 P 已经失去了它的所有踪迹

    第 4 行是罪魁祸首。 Excel 作为服务运行,因为注册表项表明它是 DCOM 对象。解决这个问题的一种方法是创建一个 shell 对象,并通过它运行应用程序。

    dim shell = wscript.createObject("wscript.shell")
    shell.run(<path-to-application>\excel.exe)
    

    缺点是必须知道应用程序的路径。

    【讨论】:

      猜你喜欢
      • 2021-05-05
      • 1970-01-01
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      相关资源
      最近更新 更多