您好,MS。有趣的问题;我想以前没人问过我们这个问题。 乍一看,真难倒我们了;毕竟没有任何 WMI 类或 COM 对象用来管理屏幕保护程序,我们也不知道每次屏幕保护程序启动时触发的事件,至少不知道能使用上脚本的事件。 这些困难足以构成一个极为复杂繁琐的问题,我们可能要花上几年时间才能解决。
或者,正如最终的结果,解决这个问题可能只需要几分钟:
strComputer = "atl-dc-01"
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcesses
If Right(objProcess.Name, 4) = ".scr" Then
Wscript.Echo "The screen saver " & objProcess.Name & " is running."
Wscript.Echo "Screen saver start time: " & objProcess.CreationDate
Wscript.Quit
End If
Next
Wscript.Echo "The screen saver is not running."
老实说,起初我们有点小题大做了。 当然,不存在用于管理屏幕保护程序的 COM 对象,也没有屏幕保护程序启动时触发的事件。但这没关系。 屏幕保护程序运行时,通常运行的是一个文件扩展名为 .scr 的文件。 如果我们想知道屏幕保护程序是否在运行,我们所要做的就是检查是否有正在运行的进程,它的可执行文件以 .scr 结尾。 如果有,这很可能意味着屏幕保护程序正在运行。
|
注意。 我们清楚这并不保险,很可能存在第三方屏幕保护程序使用不同的文件扩展名。 但这一方法对于同操作系统一起安装的屏幕保护程序应该能起作用。 |
既然了解了策略,让我们研究一下脚本。 有一点您可能注意到了,第一行代码与我们大多数的 WMI 示例脚本稍有不同:
strComputer = "atl-dc-01"
通常,我们的第一行代码将变量 strComputer 的值设置为点 (.);我们这么做是因为点表示本地计算机,将 strComputer 设置为点使得脚本运行于本地计算机而不用考虑此台计算机的名称。 不过我们假定您想对远程机器运行此脚本;要判断您本地计算机是否有屏幕保护程序在运行可能有更容易的方法,而不用编写脚本。 因此,我们将 strComputer 的值设置为远程机器的名称,本例中为 atl-dc-01。
接下来,我们连接 Win32_Process 类,使用 ExecQuery 方法检索在计算机 atl-dc-01 上运行的所有进程的集合。然后建立 For Each 循环遍历此集合。 在循环内,我们检查每一进程的 Name 属性的值(此值相当于应用程序的文件名)。 如果 Name 以 .scr 结束,我们假定屏幕保护程序正在运行,回显屏幕保护程序的可执行文件名及其启动时间。 (我们可以通过 CreationDate 属性检索该值。) 找到屏幕保护程序后,然后调用 Wscript.Quit 方法退出脚本。
我们如何知道可执行文件名是否以 .scr 结尾? 我们只要使用 VBScript Right 函数,让它检查字符串的最后四个字符:
If Right(objProcess.Name, 4) = ".scr" Then
但是如果我们没有发现其名称以 .scr 结尾的进程怎么办? 在检查每一进程后,我们退出循环,然后回显消息表明屏幕保护程序没有运行。
我们运行此脚本时,得到类似以下的输出:
The screen saver logon.scr is running.
Screen saver start time: 20050725153639.115344-420
是的,这是个好问题: 得到的启动时间是 UTC(世界调整时间)格式,并不是最直观的日期时间格式。 因此,让我们修改脚本以包括一个函数,用来将此 UTC 日期时间格式转换成可读性更强的形式:
strComputer = "atl-dc-01"
Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcesses
If Right(objProcess.Name, 4) = ".scr" Then
Wscript.Echo "The screen saver " & objProcess.Name & " is running."
dtmStartTime = objProcess.CreationDate
dtmScreensaverStart = WMIDateStringToDate(dtmStartTime)
Wscript.Echo "Screen saver start time: " & dtmScreensaverStart
Wscript.Quit
End If
Next
Wscript.Echo "The screen saver is not running."
Function WMIDateStringToDate(dtmBootup)
WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & "/" & _
Mid(dtmBootup, 7, 2) & "/" & Left(dtmBootup, 4) _
& " " & Mid (dtmBootup, 9, 2) & ":" & _
Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup,13, 2))
End Function
我们运行此脚本时,得到更易理解的输出结果:
The screen saver logon.scr is running.
Screen saver start time: 7/25/2005 3:36:39 PM
|
注意。 我们将不讨论用于将 UTC 日期转换到常规日期的函数,不过您可以在 Microsoft Windows 2000 Scripting Guide(英文)的此部分了解到这一过程。 |
正如我们所言,确定屏幕保护程序是否运行原来相当简单。 这使我们好奇是否人们正一直使得这一类似 cold fusion 的东西比它本应的要更棘手……