{"id":56203,"date":"2008-02-14T22:59:00","date_gmt":"2008-02-14T22:59:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/02\/14\/how-can-i-run-a-subroutine-in-an-hta-after-a-set-amount-of-time\/"},"modified":"2008-02-14T22:59:00","modified_gmt":"2008-02-14T22:59:00","slug":"how-can-i-run-a-subroutine-in-an-hta-after-a-set-amount-of-time","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-run-a-subroutine-in-an-hta-after-a-set-amount-of-time\/","title":{"rendered":"How Can I Run a Subroutine in an HTA After a Set Amount of Time?"},"content":{"rendered":"<p><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hey, Scripting Guy! I have an HTA that asks users to either click a button to install some software or click <b>Cancel<\/b>. Sometimes, though, users don\u2019t do either one; they just let the HTA sit there. Is there any way to show the HTA for a set amount of time and then, if nothing happens, have it go ahead and install the software?<\/p>\n<p>&#8212; TN<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><img decoding=\"async\" class=\"farGraphic\" title=\"Script Center\" height=\"288\" alt=\"Script Center\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" align=\"right\" border=\"0\" \/><\/a> <\/p>\n<p>Hey, TN. Well, today is February 14<sup>th<\/sup>, which just happens to be a very exciting and much-anticipated holiday. Yes, February 14<sup>th<\/sup> is that very special day, the day in which \u2013 what\u2019s that? Valentine\u2019s Day? Hold on a second \u2026 well, what do you know: today <i>is<\/i> Valentine\u2019s Day. Wow. You know, we feel kind of sorry for the people who sell Valentine\u2019s Day cards and candy; what bad luck that Valentine\u2019s Day happens to fall on the same day as a very exciting and much-anticipated holiday.<\/p>\n<p>What holiday are <i>we<\/i> talking about? You must be joking, right? After all, <i>everyone<\/i> knows that today, February 14<sup>th<\/sup>, is Scripting Games Eve. That\u2019s right, today is the day when people, giddy with expectations, make their final plans for the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/default.mspx\"><b>2008 Winter Scripting Games<\/b><\/a>, which officially kick off on Friday, February 15<sup>th<\/sup>. Sometime after midnight tonight, the Scripting Guys will climb into the Scripting Sleigh and fly all around the world, slipping down chimneys and leaving Scripting Games events for all the good little boys and girls.<\/p>\n<p>OK, so maybe that was a bit of an exaggeration. The truth is, the Scripting Guys won\u2019t be slipping down any chimneys, not unless the Scripting Guy who writes this column stops eating doughnuts every morning. (Getting stuck in someone\u2019s chimney would be <i>way<\/i> too embarrassing.) However, we <i>do<\/i> plan to post the Scripting Games events sometime after midnight Pacific Standard Time. (See <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/feb08\/hey0213.mspx\"><b>this column<\/b><\/a> and <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/games08\/timezones.mspx\"><b>this Web page<\/b><\/a> for information on converting Pacific Standard Time to your local time.) And these will be available to everyone, not just the good little boys and girls.<\/p>\n<p>After all, if we limited this to good little boys and girls the neither Scripting Guy Dean Tsaltas nor Scripting Guy Peter Costantini would be able to take part.<\/p>\n<p>Now that you mention it, yes, that <i>is<\/i> a change in plans: originally we intended to post all the Scripting Games events at 8:00 AM Redmond time on February 15<sup>th<\/sup>. After giving this a little thought, however, we decided to post things a bit sooner than that; we saw that as a way to help out those of you who don\u2019t live in the Pacific Standard Time time zone. (Which we still think is the greatest time zone in the world. You go, Pacific Standard Time time zone!)<\/p>\n<p>At any rate, a Happy Scripting Games Eve to everyone, regardless of which time zone you live in. We know that many of you are very excited about the Scripting Games, so excited that you can\u2019t even sleep. If that sounds like you, well, here\u2019s a little something that will help you pass the time between now and the moment the Scripting Games events become available. This little something happens to be code for an HTML Application (HTA). But not just <i>any<\/i> HTA: this one waits to see if a user is going to click a button and then, if the user doesn\u2019t do anything, goes ahead and runs a subroutine on its own. Here\u2019s the code: <\/p>\n<pre class=\"codeSample\">&lt;SCRIPT Language = \"VBScript\"&gt;\n    Dim idTimer\n\n    Sub Window_Onload\n        idTimer = window.setTimeout(\"InstallSoftware\", 5000, \"VBScript\")\n    End Sub\n\n    Sub InstallSoftware\n        window.clearTimeout(idTimer)\n        Msgbox \"Installing software ...\"\n    End Sub\n\n    Sub CancelInstall\n        window.clearTimeout(idTimer)\n        Msgbox \"Installation cancelled.\"\n    End Sub\n&lt;\/SCRIPT&gt;\n\n&lt;BODY&gt;\n    &lt;input type=\"button\" value=\"Install\" onClick=\"InstallSoftware\"&gt;\n    &lt;input type=\"button\" value=\"Cancel\" onClick=\"CancelInstall\"&gt;\n&lt;\/BODY&gt;\n<\/pre>\n<p>As you can see, there\u2019s not much to this HTA. For example, the HTA &lt;BODY&gt; consists of just two buttons. The first button, labeled <b>Install<\/b>, is configured to run a subroutine named InstallSoftware any time the button is clicked:<\/p>\n<pre class=\"codeSample\">&lt;input type=\"button\" value=\"Install\" onClick=\"InstallSoftware\"&gt;\n<\/pre>\n<p>The second button, labeled <b>Cancel<\/b>, is configured to run a subroutine named CancelInstall any time that <i>it<\/i> gets clicked:<\/p>\n<pre class=\"codeSample\">&lt;input type=\"button\" value=\"Cancel\" onClick=\"CancelInstall\"\n<\/pre>\n<p>And that\u2019s it. We told you there wasn\u2019t much to this.<\/p>\n<p>Now let\u2019s take a look at the &lt;SCRIPT&gt; section of our HTA. To begin with, you might notice that we have one line of code that isn\u2019t contained within a subroutine:<\/p>\n<pre class=\"codeSample\">Dim idTimer\n<\/pre>\n<p>What we\u2019re doing here is declaring a global variable named idTimer. By default, variables used in an HTA are accessible only to the subroutine where those variables are declared or first used. For example, consider this subroutine:<\/p>\n<pre class=\"codeSample\">Sub VariableTest\n    Dim strTest\nEnd Sub\n<\/pre>\n<p>Because strTest was declared inside the subroutine VariableTest that\u2019s the <i>only<\/i> place that variable can be used; you can\u2019t retrieve the value of strTest from another subroutine. The only time you can access a variable from another subroutine is when that variable is a global variable. And how do you create a global variable? You got it: you declare it inside the &lt;SCRIPT&gt; section of the HTA. (But <i>not<\/i> inside a subroutine.) Just do what we did, and have the Dim statement sitting on a line all by itself.<\/p>\n<p>After declaring our global variable we next encounter this subroutine:<\/p>\n<pre class=\"codeSample\">Sub Window_Onload\n    idTimer = window.setTimeout(\"InstallSoftware\", 5000, \"VBScript\")\nEnd Sub\n<\/pre>\n<p>As most of you probably know, in an HTA any subroutine named <b>Window_Onload<\/b> will automatically run any time that HTA is loaded or refreshed. So what are we going to do each time the HTA is loaded or refreshed? Just one thing; we\u2019re going to use the <b>setTimeout <\/b>method to create a timer named <b>idTimer<\/b>:<\/p>\n<pre class=\"codeSample\">idTimer = window.setTimeout(\"InstallSoftware\", 5000, \"VBScript\")\n<\/pre>\n<p>A timer is pretty much what the name implies: it\u2019s a control that\u2019s going to count down for a specified amount of time and then take some sort of action. To create a timer we simply call the setTimeout method, passing setTimeout three parameters:<\/p>\n<table class=\"\" cellSpacing=\"0\" cellPadding=\"0\" border=\"0\">\n<tbody>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>InstallSoftware<\/b>. This is the name of the subroutine we want to run after the allotted time has elapsed.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>5000<\/b>. This is the amount of milliseconds we want to count down. Because there are 1000 milliseconds in every second that means our 5000-millisecond timer will count down for 5 seconds before calling the subroutine InstallSoftware.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"listBullet\" vAlign=\"top\">\u2022<\/td>\n<td class=\"listItem\">\n<p><b>VBScript<\/b>. This simply tells the HTA which scripting language the InstallSoftware subroutine is written in.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>So what\u2019s all this going to do? Well, when the HTA first loads up it\u2019s going to create the timer idTimer and the clock is going to begin ticking. After 5 seconds have elapsed, and if the user hasn\u2019t done anything else, the timer will then call the subroutine InstallSoftware.<\/p>\n<p>Speaking of which, let\u2019s take a look at the InstallSoftware subroutine:<\/p>\n<pre class=\"codeSample\">Sub InstallSoftware\n    window.clearTimeout(idTimer)\n    Msgbox \"Installing software ...\"\nEnd Sub\n<\/pre>\n<p>Again, pretty simple stuff here. In the first line we use the <b>clearTimeout<\/b> method to cancel our timer idTimer. Is that important? As a matter of fact it is: if we don\u2019t explicitly cancel the timer then that timer will continue to run; in this case, that means that every 5 seconds the HTA will call the InstallSoftware subroutine. That\u2019s probably <i>not<\/i> what we want it to do.<\/p>\n<p>In line 2 we display a message box that notes that the software is being installed. Obviously you don\u2019t need a message box here. (And you probably shouldn\u2019t display one anyway. After all, that would cause the subroutine to stop dead in its tracks, at least until someone dismissed the message box.) Instead, this would be the spot where you put your code for installing the software, or for doing whatever it is you want the HTA to do.<\/p>\n<p>To recap, we start the HTA, the timer starts ticking and, after 5 seconds the InstallSoftware subroutine kicks in. All of that happens automatically, without any user intervention. So then what do we need those two buttons for?<\/p>\n<p>To answer that question, let\u2019s first note that we configured out timer for 5 seconds simply for testing purposes. In real life, 5 seconds might not be enough time for a user to decide whether or not they want to install the software. Instead, you might create a timer that runs for, say, 30 seconds:<\/p>\n<pre class=\"codeSample\">idTimer = window.setTimeout(\"InstallSoftware\", 30000, \"VBScript\")\n<\/pre>\n<p>Now, if you wanted to, you could simply make your user sit there for 30 seconds and wait for the InstallSoftware subroutine to start up. Alternatively, that user could click the <b>Install<\/b> button and \u201cmanually\u201d kick off the installation process at any time. Click the <b>Install<\/b> button and \u2013 regardless of how much time has elapsed \u2013 the timer will be cleared and software installation will begin.<\/p>\n<table class=\"dataTable\" id=\"ERH\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p class=\"lastInCell\"><b>Note<\/b>. It\u2019s important to keep in mind that this timer is not pausing the entire HTA; that is, it\u2019s not functioning like the Wscript.Sleep command. Instead, the timer is running in the background, leaving us free to do other things in the HTA. Like, say, click one of buttons.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>OK, now what about the <b>Cancel<\/b> button? Well, TN wants to give users the opportunity to cancel software installation. To do that, all they have to do is click the <b>Cancel<\/b> button, which, in turn, calls the following subroutine:<\/p>\n<pre class=\"codeSample\">Sub CancelInstall\n    window.clearTimeout(idTimer)\n    Msgbox \"Installation cancelled.\"\nEnd Sub\n<\/pre>\n<p>Notice what we\u2019re doing in <i>this<\/i> subroutine. To begin with, we once again use the clearTimeout method to get rid of our timer. As soon as that\u2019s done we display a message box noting that the installation process has been cancelled. But, again, that\u2019s code we\u2019re using merely for demonstration purposes; put whatever code you want here. For example, you could include this line of code, which causes the HTA to close any time a user clicks the <b>Cancel<\/b> button:<\/p>\n<pre class=\"codeSample\">window.close()\n<\/pre>\n<p>Alternatively, you could leave the HTA onscreen. That way the user could still install the software simply by clicking the <b>Install<\/b> button. But that\u2019s up to you.<\/p>\n<p>That\u2019s should do it, TN; hopefully you can take this sample code and make it fit your exact needs. In the meantime, we\u2019d like to once again wish everyone a very Happy Scripting Games Eve; we hope to see you back here tomorrow for <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/default.mspx\"><b>Opening Day<\/b><\/a>. (February, 15<sup>th<\/sup>, in case if we haven\u2019t mentioned that enough times yet.) We should also point out that we know that way more people read this column each day than participate in the Games. Hey, what\u2019s up with <i>that<\/i>? Come on, give the Scripting Games a try: it\u2019s fun; it\u2019s educational; you can compete anonymously if you want; and, best of all, you have numerous chances to win some <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/funzone\/games\/games08\/prizes.mspx\"><b>great prizes<\/b><\/a>. Based on all that, why <i>wouldn\u2019t<\/i> you want to give the Games a try? <\/p>\n<p>We should also take a minute to wish all of you a Happy Valentine\u2019s Day. Did you know that, in Japan, it\u2019s obligatory for women to give all their male co-workers chocolates on Valentine\u2019s Day? It\u2019s true. Are you listening, Scripting Guy Jean Ross?<\/p>\n<p><b>Ed<\/b><b>itor\u2019s Note:<\/b> Scripting Guy Jean Ross has no problem with that. That just means that as of March 14 (\u201cWhite Day\u201d in Japan) she can expect to finally get that new watch she\u2019s been hoping for \u2026.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have an HTA that asks users to either click a button to install some software or click Cancel. Sometimes, though, users don\u2019t do either one; they just let the HTA sit there. Is there any way to show the HTA for a set amount of time and then, if nothing happens, [&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":[3,4,5,30],"class_list":["post-56203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-vbscript","tag-web-pages-and-htas"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have an HTA that asks users to either click a button to install some software or click Cancel. Sometimes, though, users don\u2019t do either one; they just let the HTA sit there. Is there any way to show the HTA for a set amount of time and then, if nothing happens, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56203","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=56203"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/56203\/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=56203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=56203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=56203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}