{"id":67983,"date":"2006-02-10T14:41:00","date_gmt":"2006-02-10T14:41:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/02\/10\/how-can-i-log-the-start-time-and-the-end-time-of-the-screensaver\/"},"modified":"2006-02-10T14:41:00","modified_gmt":"2006-02-10T14:41:00","slug":"how-can-i-log-the-start-time-and-the-end-time-of-the-screensaver","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-log-the-start-time-and-the-end-time-of-the-screensaver\/","title":{"rendered":"How Can I Log the Start Time and the End Time of the Screensaver?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I log the start time and the end time of the screensaver?<BR><BR>&#8212; JS<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, JS. You know, one of the Scripting Guys (hey, who said \u201cIt must be Greg\u201d?) is old enough to remember the days when screensavers first came out. Back then a script like this would have been meaningless: after all, once a screensaver started everyone was so fascinated by it they never wanted it to end. In fact, one of the first things this Scripting Guy had to do as a computer support person was to make little shortcuts on everyone\u2019s desk so that they could launch their Flying Toasters any time they wanted.<\/P>\n<P>People were so easy to amuse back then.<\/P>\n<P>Ah, but there\u2019s no point living in the past, right? In today\u2019s modern world you obviously have a need not only to stop a screensaver, but to take note of <I>when<\/I> it stopped. With that in mind, let\u2019s take a look at a WMI event monitoring script that will keep track of each time a screen saver starts and stops:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;\nSet objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>Set objEventSource = objWMIService.ExecNotificationQuery _\n    (&#8220;SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA &#8216;Win32_Process'&#8221;)<\/p>\n<p>Do While True\n    Set objEventObject = objEventSource.NextEvent()\n        If Right(objEventObject.TargetInstance.Name, 4) = &#8220;.scr&#8221; Then\n        Select Case objEventObject.Path_.Class\n            Case &#8220;__InstanceCreationEvent&#8221;\n                Wscript.Echo &#8220;Screensaver &#8221; &amp; objEventObject.TargetInstance.Name &amp; _\n                    &#8221; started: &#8221; &amp; Now\n            Case &#8220;__InstanceDeletionEvent&#8221;\n                Wscript.Echo &#8220;Screensaver &#8221; &amp; objEventObject.TargetInstance.Name &amp; _\n                    &#8221; ended: &#8221; &amp; Now\n        End Select\n    End If\nLoop\n<\/PRE>\n<P>Yes, it <I>does<\/I> look a little complicated, doesn\u2019t it? But don\u2019t panic: by design WMI event scripts always look a little complicated. Fortunately, the scripts only <I>look<\/I> complicated; as you\u2019ll see they\u2019re really not all that hard to understand.<\/P>\n<TABLE id=\"EHD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. OK, we\u2019d better qualify that last statement: they\u2019re not all that hard to understand as long as you\u2019ve been exposed to the basic ideas behind WMI eventing. If that isn\u2019t the case, then you might want to take time out and watch this <A href=\"http:\/\/msevents.microsoft.com\/cui\/eventdetail.aspx?EventID=1032268754&amp;culture=en-US\" target=\"_blank\"><B>Scripting Week 2 webcast<\/B><\/A>. The webcast will give you all the background information you need to make sense of today\u2019s column.<\/P>\n<P>Good point; probably <I>nothing<\/I> will help you make sense of one of our columns. But at least it\u2019ll help you make sense of the script code.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>This particular script begins in the time-honored fashion of connecting to the WMI service on the local computer. It\u2019s right about here that we usually execute a WMI query to return information. As it turns out, we\u2019re going to do that in this script, too; it\u2019s just that our query is going to look a little different:<\/P><PRE class=\"codeSample\">Set objEventSource = objWMIService.ExecNotificationQuery _\n    (&#8220;SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA &#8216;Win32_Process'&#8221;)\n<\/PRE>\n<P>Needless to say, this isn\u2019t the type of WMI query you\u2019re used to writing; for one thing, we\u2019re calling the <B>ExecNotificationQuery<\/B> method rather than ExecQuery. (Why? Because ExecNotificationQuery is the method you <I>have<\/I> to use in order to monitor WMI events.) We won\u2019t explain this query in minute detail today, but suffice to say that we\u2019re asking WMI to notify us any time a WMI event occurs (something is created, something is deleted, something is modified). There\u2019s just one catch: we want to be notified only if the <B>TargetInstance<\/B> (the item being created, deleted, or modified) is an instance of the Win32_Process class.<\/P>\n<TABLE id=\"EKE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. OK, technically there\u2019s a second catch: we\u2019re only checking for new events every 5 seconds. If the screensaver starts and then ends 3 seconds later, we\u2019ll probably never be notified.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>In other words, suppose a new file is created. Is a new file an instance of the Win32_Process class? Nope; it\u2019s an instance of the CIM_DataFile class. Therefore, we don\u2019t want to be notified. Suppose a service gets modified. Do we want notification? No; a service is an instance of the Win32_Service class. OK then, suppose a new process &#8211; like a screensaver &#8211; starts up. Do we want to be notified? You bet: after all, a new process <I>is<\/I> an instance of the Win32_Process class. We want to be notified any time a process is created, deleted, or modified. <\/P>\n<P>But you already figured that out, didn\u2019t you?<\/P>\n<P>In order to get these notifications we set up a Do loop that runs while True is equal to True:<\/P><PRE class=\"codeSample\">Do While True\n<\/PRE>\n<P>That\u2019s kind of weird syntax, but it\u2019s a syntax that enables the script to continue to run &#8211; and continue to monitor the creation, deletion, and modification of processes &#8211; until we either terminate the script or restart the computer. If we didn\u2019t have a loop like this, the script would notify us that a screensaver had started, but then the script would end. Consequently, we\u2019d never be notified when the screensaver ended.<\/P>\n<P>The first thing we do inside the loop is execute this line of code:<\/P><PRE class=\"codeSample\">Set objEventObject = objEventSource.NextEvent()\n<\/PRE>\n<P>What we\u2019re doing here is telling the script to wait until the next event of interest occurs; in other words, the script will sit on this line of code until a process is created, deleted, or modified. Suppose our processes never change, suppose we <I>never<\/I> create, delete, or modify a process. Well, in that case the script will simply sit here forever, waiting patiently. Just in case.<\/P>\n<P>Now, we know what you\u2019re thinking. You\u2019re thinking: \u201cHey, wait a second. We only care about screensavers. Microsoft Word runs in a process. If we start Microsoft Word, thus creating a new instance of the Winword.exe process, won\u2019t that trigger a notification?\u201d <\/P>\n<P>You\u2019re right: it will. And that\u2019s what our next line of code is for. Starting up Word (or any executable file, for that matter) will, indeed, issue a notification. But we can account for that by using this line of code:<\/P><PRE class=\"codeSample\">If Right(objEventObject.TargetInstance.Name, 4) = &#8220;.scr&#8221; Then\n<\/PRE>\n<P>Here we\u2019re using the <B>Right<\/B> function to check the <B>Name<\/B> of the process that triggered the notification. If the rightmost four characters in the name are equal to <I>.scr<\/I>, then we\u2019re assuming that we\u2019re dealing with a screensaver; that\u2019s because screensavers have names like Marquee<B>.scr<\/B>. If the last four characters in the name <I>aren\u2019t<\/I> .scr then we simply loop around and wait for the next event to occur.<\/P>\n<P>So what if the last four characters <I>are<\/I> .scr? Well, in that case we\u2019re interested in two possibilities: a screensaver started or a screensaver ended. (We don\u2019t care whether or not someone modifies the properties of a screensaver.) To handle these two possibilities we set up a Select Case block that examines the <B>Class<\/B> of the event instance:<\/P><PRE class=\"codeSample\">Select Case objEventObject.Path_.Class\n<\/PRE>\n<P>If the Class is equal to <B>__InstanceCreationEvent<\/B>, that means a new process (i.e., a new screensaver) has been created. In our first Case statement we check to see if the Class is equal to __InstanceCreationEvent. If it is, we echo the fact that a particular screensaver (represented by the process name) started at a particular time (using the VBScript function <B>Now<\/B>):<\/P><PRE class=\"codeSample\">Case &#8220;__InstanceCreationEvent&#8221;\n    Wscript.Echo &#8220;Screensaver &#8221; &amp; objEventObject.TargetInstance.Name &amp; &#8221; started: &#8221; &amp; Now\n<\/PRE>\n<P>That makes sense, doesn\u2019t it? Now, suppose the screensaver has ended, something which would cause the screensaver process to be deleted. To handle that possibility, we check for any new instances of the <B>__InstanceDeletionEvent <\/B>class. If our event happens to belong to that class (meaning a screensaver process has been deleted) we echo the fact that a given screensaver stopped at a given time:<\/P><PRE class=\"codeSample\">Case &#8220;__InstanceDeletionEvent&#8221;\n    Wscript.Echo &#8220;Screensaver &#8221; &amp; objEventObject.TargetInstance.Name &amp; &#8221; ended: &#8221; &amp; Now\n<\/PRE>\n<P>And there you have it. When you run the script you\u2019ll get back information similar to this:<\/P><PRE class=\"codeSample\">Screensaver Script Center.scr started: 2\/9\/2006 9:11:07 AM\nScreensaver Script Center.scr ended: 2\/9\/2006 9:11:17 AM\n<\/PRE>\n<TABLE id=\"ETG\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. What the heck is <B>Script Center.scr<\/B>? <A href=\"http:\/\/null\/downloads\/details.aspx?FamilyID=0c0858e5-d551-4c76-a342-ea5de30bc7a1&amp;displaylang=en\" target=\"_blank\"><B>Download it<\/B><\/A> and find out.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Two things we should add. First, this script is best run in a command window under Cscript; that means that, to start the thing, you might want to open a command window and type something like this (depending on what you name the script, of course):<\/P><PRE class=\"codeSample\">cscript screensaver_monitor.vbs\n<\/PRE>\n<P>Second, and as we pointed out, this script is designed to run forever. On the other hand, nothing lasts forever, does it? If you want to stop monitoring all you have to do is press Ctrl+C, close the command window, or terminate the CScript.exe process. Remember, the Scripting Guys would never leave you trapped inside an endless loop with no way out. (What do you know: that\u2019s a pretty good description of our jobs right there.)<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I log the start time and the end time of the screensaver?&#8212; JS Hey, JS. You know, one of the Scripting Guys (hey, who said \u201cIt must be Greg\u201d?) is old enough to remember the days when screensavers first came out. Back then a script like this would have been [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[16,42,47,3,4,5],"class_list":["post-67983","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-desktop-management","tag-events-and-monitoring","tag-general-management-tasks","tag-scripting-guy","tag-scripting-techniques","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I log the start time and the end time of the screensaver?&#8212; JS Hey, JS. You know, one of the Scripting Guys (hey, who said \u201cIt must be Greg\u201d?) is old enough to remember the days when screensavers first came out. Back then a script like this would have been [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67983","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=67983"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67983\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=67983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}