用vbs记录屏幕保护程序的开始时间和结束时间

问:
您好,脚本专家!如何记录屏幕保护程序的开始时间和结束时间?
-- JS
答:
您好,JS。您知道,一位脚本专家(嘿,谁说“肯定是 Greg”?)年纪大得记得屏幕保护程序刚出现的日子。那时,这类脚本毫无意义。毕竟,屏幕保护程序启动后,每个人都神魂颠倒,从未想过让它结束。事实上,作为计算机支持人员的这位脚本专家首先必须做的一件事就是在每个人的桌面上创建快捷方式,使他们能够随时启动“飞转的小烤炉”。
那时人们很容易得到快乐。
啊,但是活在过去没有意义,对吧?在今天的现代社会中,显然不仅需要停止屏幕保护程序,还需要记录停止的时间。明确这一点后,让我们来看一看下面这个 WMI 事件监控脚本,它会跟踪屏幕保护程序的每次启动和停止:


代码如下:

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
Set objEventSource = objWMIService.ExecNotificationQuery _ 
    ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'") 
Do While True 
    Set objEventObject = objEventSource.NextEvent() 
        If Right(objEventObject.TargetInstance.Name, 4) = ".scr" Then 
        Select Case objEventObject.Path_.Class 
            Case "__InstanceCreationEvent" 
                Wscript.Echo "Screensaver " & objEventObject.TargetInstance.Name & _ 
                    " started: " & Now 
            Case "__InstanceDeletionEvent" 
                Wscript.Echo "Screensaver " & objEventObject.TargetInstance.Name & _ 
                    " ended: " & Now 
        End Select 
    End If 
Loop

它看起来的确有点复杂,不是吗?但是别慌:就设计而言,WMI 事件脚本总是看起来有点复杂。幸运的是,这些脚本只是看起来复杂;您会看到,这些脚本实际上并不那么难理解。
注意:好吧,我们最好对最后一句陈述加以限定:只要您了解 WMI 事件构成的基本思想,就不那么难理解。如果您还不了解,最好花点时间看看脚本编写第 2 周网络广播。这个网络广播将为您提供了理解今天专栏文章所需的所有背景信息。
好主意!尽管可能没有有助于搞清楚我们的某一篇专栏文章的信息,但至少有助于搞清楚这个脚本代码的意思。
这个特定脚本的开始是以历史悠久的方式连接到本地计算机上的 WMI 服务。通常到这里,我们要执行 WMI 查询以返回信息。正如您所看到的,在这个脚本中我们也要这么做,只是查询看起来有点不同:
Set objEventSource = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'")
不用说,这不是您所习惯编写的 WMI 查询类型,因为我们调用的是 ExecNotificationQuery 方法,而不是 ExecQuery。(为什么呢?因为要监控 WMI 事件,就必须使用 ExecNotificationQuery 方法。)今天我们无法详细解释这个查询,但我们可以说,我们要求 WMI 只要有 WMI 事件(创建、删除、修改)发生,就立刻通知我们。这里只有一个问题:我们只想当 TargetInstance(创建、删除或修改的项目)是 Win32_Process 类的实例时才得到通知。
注意:当然,从技术角度来说,还有第二个问题:我们只是每 5 秒钟检查一次新事件。如果屏幕保护程序启动,3 秒钟之后结束,我们很可能就不会得到通知了。
换句话说,假设创建了一个新文件。新文件是 Win32_Process 类的实例吗?不是;它是 CIM_DataFile 类的实例。因此,我们不想得到通知。假设修改了一个服务。我们想要得到通知吗?不想要,因为服务是 Win32_Service 类的实例。好了,假设新进程(例如屏幕保护程序)启动。我们想要得到通知吗?当然想要。别忘了,新进程可是 Win32_Process 类的实例。任何时候如果创建、删除或修改进程,我们都想得到通知。 
不过,这些您已经意识到了,对吧?
为了获得这些通知,我们建立一个当 True 等于 True 时运行的 Do 循环:
Do While True
句子的语法确实有点怪异,但这个语法却能够使脚本不停运行,并且不停监控进程的创建、删除和修改,直到终止脚本或重新启动计算机。如果没有这样的循环,脚本会通知我们屏幕保护程序何时启动,但是,随后脚本就会结束。结果,我们永远也不会得到屏幕保护程序何时结束的通知。
在循环内,我们首先要做的就是执行下面这行代码:
Set objEventObject = objEventSource.NextEvent()
我们所做的是告诉脚本等待,直到下一个我们所关心的事件发生。换句话说,脚本将停留在此行代码上,直到有进程被创建、删除或修改。假设进程始终不变,假设我们始终不创建、删除或修改进程。在这种情况下,脚本就会永远停在这儿,耐心等待。以防万一。
现在,我们知道您正在想什么。您正在想:“嗨,稍等一下。我们只关心屏幕保护程序。Microsoft Word 也在进程中运行。如果我们启动 Microsoft Word,从而创建 Winword.exe 进程的新实例,那不也会触发通知吗?” 
您说对了:会触发通知。接下来这行代码就用来解决这个问题。启动 Word(或者任何可执行文件,就这一点而言)确实都会发出通知。但我们可以使用下面这行代码解决这个问题:
If Right(objEventObject.TargetInstance.Name, 4) = ".scr" Then
在这里,我们使用 Right 函数检查触发通知的进程的名称。如果名称中最右侧的四个字符等于 .scr,我们便假定正在处理的是屏幕保护程序,因为屏幕保护程序的名称类似 Marquee.scr。如果名称中的最后四个字符不是 .scr,我们便只是循环一次,然后等待下一个事件发生。
那么,如果最后四个字符是 .scr 会怎样?在这种情况下,我们只关心两种可能:屏幕保护程序启动或屏幕保护程序结束。(我们并不关心是否有人修改屏幕保护程序的属性。)为处理这两种可能,我们设置一个 Select Case 块,用于检查事件实例的 Class:
Select Case objEventObject.Path_.Class
如果 Class 等于 __InstanceCreationEvent,则意味着已创建新进程(即新屏幕保护程序)。在第一个 Case 语句中,我们检查 Class 是否等于 __InstanceCreationEvent。如果等于,我们便回显如下事实:特定屏幕保护程序(使用进程名称表示)在特定时间(使用 VBScript 函数 Now)启动:
Case "__InstanceCreationEvent"
    Wscript.Echo "Screensaver " & objEventObject.TargetInstance.Name & " started: " & Now
意思清楚了,对吧?现在,假设屏幕保护程序已结束,这就会导致删除屏幕保护程序进程。为处理这种可能,我们检查 __InstanceDeletionEvent 类是否有新实例。如果发生属于该类的事件(表示已删除屏幕保护程序进程),我们便回显如下事实 - 指定的屏幕保护程序在指定时间停止:
Case "__InstanceDeletionEvent"
    Wscript.Echo "Screensaver " & objEventObject.TargetInstance.Name & " ended: " & Now
至此您已实现了您的目的。运行此脚本后,会返回类似下面的信息:
Screensaver Script Center.scr started: 2/9/2006 9:11:07 AM
Screensaver Script Center.scr ended: 2/9/2006 9:11:17 AM
注意:Script Center.scr 到底是什么?下载它,然后自己看。
我们还要补充两件事。第一,最好在 Cscript 下的命令窗口中运行此脚本,也就是说,要开始监控,请打开命令窗口,然后键入类似下面的命令(当然,具体内容视脚本名称而定):
cscript screensaver_monitor.vbs
第二,正如我们前面所指出的,此脚本设计为永远运行。另一方面,什么事都不会永远持续下去,是吧?如果要停止监控,我们只需按 Ctrl+C,关闭命令窗口,或者终止 CScript.exe 进程。记住,脚本专家决不会让您陷于没有出口的无限循环中。(您知道吗:这对我们这的工作真是形容得非常恰当。)

(0)

相关推荐

  • 用vbs记录屏幕保护程序的开始时间和结束时间

    问: 您好,脚本专家!如何记录屏幕保护程序的开始时间和结束时间? -- JS 答: 您好,JS.您知道,一位脚本专家(嘿,谁说"肯定是 Greg"?)年纪大得记得屏幕保护程序刚出现的日子.那时,这类脚本毫无意义.毕竟,屏幕保护程序启动后,每个人都神魂颠倒,从未想过让它结束.事实上,作为计算机支持人员的这位脚本专家首先必须做的一件事就是在每个人的桌面上创建快捷方式,使他们能够随时启动"飞转的小烤炉". 那时人们很容易得到快乐. 啊,但是活在过去没有意义,对吧?在今天的

  • 用vbs实现配置无人登录计算机时使用的屏幕保护程序

    问: 您好,脚本专家!我最近下载了你们的"脚本中心"屏幕保护程序,当有人登录计算机时,它运行起来棒极了.但是无人登录时,计算机却使用其它屏幕保护程序.如何让计算机在无人登录时也使用"脚本中心"屏幕保护程序? -- RF 答: 您好,RF.您知道,我们遇到过这种情况,您可能在设法欺骗这些老脚本专家们.举个例子来说,我们怎么知道您希望无人登录计算机时运行的屏幕保护程序就是我们的屏幕保护程序?也许您只是奉承脚本专家,好让脚本专家回答您的问题.回答完问题后,您就会把我们甩掉

  • c#制作屏幕保护程序步骤(字幕屏保)

    屏幕保护程序的扩展名虽然是"scr",但其实是一个可执行的"exe"文件.但他又是一个比较独特的"exe"文件.下面就来探讨一下,用C#是如何编写屏幕保护的整个过程. 二.C#编写字幕显示屏保程序的关键步骤以及解决方法:(1)设定程序的窗体符合屏幕保护的要求:由于屏幕保护程序就是一个可执行程序,所以在编写屏幕保护程序的时候,首先按照可执行程序来设计.但屏幕保护有自身的特点.譬如:屏幕保护都是充满整个屏幕的,并且没有无边.屏幕保护运行的时候,不能显

  • 巧妙卸载公用电脑的屏幕保护程序

    学校的微机室是多个班级共用,一个班级的学生上课时指定了屏幕保护程序并设定了口令,下一个班级的学生上课时,如果在指定的时间内(最短时间为1分钟)没有使用计算机,即运行屏幕保护程序.由于这个班的学生不知道口令,所以只好按下Reset键重启计算机.此时计算机的硬盘正高速旋转,按Reset键重启计算机时会划伤存有大量数据的硬盘.长此一往,就会使硬盘夭折,不仅会丢失大量教学数据,而且还会增加学校的经济负担.因此,在学校多班并用的微机室,卸载计算机的屏幕保护程序已成为大多数教师的迫切要求.下面,笔者把自己卸

  • 卸载掉您计算机中的屏幕保护程序

    学校的微机室是多个班级共用,一个班级的学生上课时指定了屏幕保护程序并设定了口令,下一个班级的学生上课时,如果在指定的时间内(最短时间为1分钟)没有使用计算机,即运行屏幕保护程序.由于这个班的学生不知道口令,所以只好按下Reset键重启计算机.此时计算机的硬盘正高速旋转,按Reset键重启计算机时会划伤存有大量数据的硬盘.长此一往,就会使硬盘夭折,不仅会丢失大量教学数据,而且还会增加学校的经济负担.因此,在学校多班并用的微机室,卸载计算机的屏幕保护程序已成为大多数教师的迫切要求.下面,笔者把自己卸

  • jquery easyui 对于开始时间小于结束时间的判断示例

    对于开始时间小于结束时间的判断可以参考,jquery easyui里的ValidateBox进行判断 好吧!直接上代码 复制代码 代码如下: 查看内容:按时间: <input class="easyui-datetimebox" style="width: 180px" id="start2" value="${startTime}"> <span class="newfont06">

  • easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码

    一.Html代码 注意的是需要加上data-options="editable:false",不能直接修改日期 <tr> <td width="15%" class="label">合同起始日期:</td> <td width="35%"> <input value="${loan.contractBegtime}" class="f1 eas

  • laydate如何根据开始时间或者结束时间限制范围

    本文教大家如何实现laydate根据开始时间或者结束时间限制范围,供大家参考,具体内容如下 $(window).load(function(){//初始化时间控件 var cartimeDate = laydate.render({ elem: '#cartime' //用车时间 ,type: 'datetime' ,format: 'yyyy-MM-dd HH:mm' ,done:function(value, date){ returntimeDate.config.min=getDateA

  • java获取指定开始时间与结束时间之间的所有日期

    本文实例为大家分享了java获取指定开始时间与结束时间之间的所有日期的具体代码,供大家参考,具体内容如下 import java.text.SimpleDateFormat; import java.util.Calendar; public class TimerTest { public static void main(String[] args) throws Exception { String beginDate = "2016-07-16";//开始时间 String e

  • vant 时间选择器--开始时间和结束时间实例

    我就废话不多说了,大家还是直接看代码吧~ <template> <div class="linesMigrate"> <div class="conditionDiv"> <div class="singleCondition" :style="conditonStyle2" @click="showPopupDateChooseStart"> <div

随机推荐