{"id":67683,"date":"2006-03-24T08:16:00","date_gmt":"2006-03-24T08:16:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2006\/03\/24\/how-can-i-retrieve-a-list-of-the-commands-typed-into-the-run-dialog-box\/"},"modified":"2006-03-24T08:16:00","modified_gmt":"2006-03-24T08:16:00","slug":"how-can-i-retrieve-a-list-of-the-commands-typed-into-the-run-dialog-box","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-retrieve-a-list-of-the-commands-typed-into-the-run-dialog-box\/","title":{"rendered":"How Can I Retrieve a List of the Commands Typed Into the Run Dialog Box?"},"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! Sometimes I type commands in the <B>Run<\/B> dialog box that I\u2019d like to retrieve later on. I know the most recent commands I used are cached somewhere; that\u2019s because they show up when I start typing in the <B>Run<\/B> dialog box. How can I use a script to retrieve these commands?<BR><BR>&#8212; KJ<\/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, KJ. You know, our first thought upon reading your question was this: why didn\u2019t <I>we<\/I> think of that? Needless to say, the Scripting Guys have been using the <B>Run<\/B> dialog box for years, and we, too are well aware that the most recent commands (the last 26, if you\u2019re scoring at home) are cached somewhere on the computer. And yet, it never occurred to us to write a script that could retrieve this list. How could we have overlooked something so obvious?<\/P>\n<TABLE id=\"EFD\" 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>. Actually, it\u2019s not all that surprising we overlooked something so obvious. For example, the Scripting Guys have been in their current building for about a year now, yet it was only a few weeks ago that the Scripting Guy who writes this column found out that there was a stairway just down the hall from his office.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After poking around a bit we discovered that this information is stored in the registry; more specifically, it\u2019s stored as individual registry values within the registry key HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU. Is that good? You bet it is; after all, it allows us to write a script like this:<\/P><PRE class=\"codeSample\">Const HKEY_CURRENT_USER = &amp;H80000001<\/p>\n<p>strComputer = &#8220;.&#8221;<\/p>\n<p>Set objRegistry = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\default:StdRegProv&#8221;)<\/p>\n<p>strKeyPath = &#8220;Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU&#8221;\nobjRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes<\/p>\n<p>For Each strValue in arrValueNames\n    If Len(strValue) = 1 Then\n        objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strRunCommand\n        intLength = Len(strRunCommand)\n        strRunCommand = Left(strRunCommand, intLength &#8211; 2)\n        Wscript.Echo strRunCommand\n    End If   \nNext\n<\/PRE>\n<P>This script connects to the RunMRU key and then enumerates the values of all the values found there. (And, yes, we know: values of values? Such is the joy of registry terminology.) To accomplish that feat, the script starts off by defining a constant named HKEY_CURRENT_USER and setting the value to &amp;H80000001; this constant is used later on to tell the script which registry hive to work with. We then connect to the WMI service on the local computer, taking care to bind to the <B>root\\default<\/B> namespace, home of the WMI registry provider.<\/P>\n<TABLE id=\"EXD\" 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>. Can we use this same script to retrieve the most-recently used commands from a remote computer? Of course we can; just assign the name of the remote computer to the variable strComputer.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>After connecting to the WMI service, we assign the value Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU to a variable named strKeyPath. We then use the <B>EnumValues<\/B> method to grab a collection of all the registry values found in the RunMRU key:<\/P><PRE class=\"codeSample\">objRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes\n<\/PRE>\n<P>As you can see, we pass EnumValues four parameters:<\/P>\n<TABLE id=\"EJE\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Parameter<\/B><\/P><\/TD>\n<TD>\n<P class=\"lastInCell\"><B>Description<\/B><\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">HKEY_CURRENT_USER<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">The registry hive where the information can be found.<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">strKeyPath<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">The path to the RunMRU key within the HKCU hive.<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">arrValueNames<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">\u201cOut\u201d parameter that serves as place to store all the registry value names. All we do is supply EnumValues with a variable name; EnumValues will then populate this variable with all the value names found in RunMRU.<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">arrValueTypes<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">Another out parameter, this one containing data types corresponding to each value found in RunMRU. This is a required parameter, but because the values found in RunMRU all have a data type of REG_SZ we don\u2019t actually use it in the script.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>As it turns out, each command typed into the Run dialog box is given its own value in the registry; these values are assigned names using the letters A through Z (which explains why only the 26 most-recently used commands are tracked in the registry). In the registry RunMRU looks something like this:<\/P><IMG border=\"0\" alt=\"Hey, Scripting Guy!\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/runmru.jpg\" width=\"400\" height=\"296\"> \n<P><BR>After executing the EnumValues method we\u2019ll get back a collection of all these value names; in other words, our collection will consist of the letters A through Z. That\u2019s good, but what this collection <I>doesn\u2019t <\/I>contain are any of the actual commands themselves. To get the commands (which is the whole idea in the first place) we need to connect to and read each of the 26 values in the registry.<\/P>\n<P>Can we do that, can we easily connect to and read each of the 26 values in the registry? Of course we can; in fact, that\u2019s what we do in this block of code:<\/P><PRE class=\"codeSample\">For Each strValue in arrValueNames\n    If Len(strValue) = 1 Then\n        objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strRunCommand\n        intLength = Len(strRunCommand)\n        strRunCommand = Left(strRunCommand, intLength &#8211; 2)\n        Wscript.Echo strRunCommand\n    End If   \nNext\n<\/PRE>\n<P>You\u2019re right: at first glance that <I>is<\/I> a little forbidding, isn\u2019t it? Tell you what, let\u2019s show you a simplified version of this For Each loop, then we\u2019ll explain why we added some additional code to the loop. Here\u2019s the simplified loop:<\/P><PRE class=\"codeSample\">For Each strValue in arrValueNames\n    objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strRunCommand\n    Wscript.Echo strRunCommand\nNext\n<\/PRE>\n<P>What we\u2019re doing here is setting up a loop that runs through all of the registry values. To read each of those values we simply call the <B>GetStringValue<\/B> method:<\/P><PRE class=\"codeSample\">objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValue,strRunCommand\n<\/PRE>\n<P>GetStringValue gets passed four parameters: the constant HKEY_CURRENT_USER; the variable strKeyPath; the variable strValue (which represents the individual value name, e.g., A, B, or C); and an out parameter named strRunCommand. With this out parameter we simply specify a variable name and the GetStringValue method assigns it the value of the registry value (that is, the appropriate Run command). After calling GetStringValue we echo back strRunCommand, loop around, and tackle the next value in the collection.<\/P>\n<P>So much for the simplified For Each loop; now what about all that extra code in our <I>real<\/I> For Each loop? The extra code is there primarily to give us slightly-nicer output. For example, in the RunMRU key there\u2019s a registry value named <B>MRUList<\/B>. This doesn\u2019t represent an actual command; instead, it represents the order in which the most recently-used commands are presented. That\u2019s not important to us (at least not today), so we\u2019d just as soon skip the MRUList value altogether. That\u2019s\u2019 what we do here:<\/P><PRE class=\"codeSample\">If Len(strValue) = 1 Then\n<\/PRE>\n<P>In this line of code we use the <B>Len<\/B> function to check the number of characters in the value name. If the number of characters (length) is equal to 1 we go ahead and read the value. If the length is <I>not<\/I> equal to 1 (which, obviously, is the case with MRUList, which has 7 characters) then we simply skip that value and move on to the next item in the collection.<\/P>\n<P>The other little touch we added was this:<\/P><PRE class=\"codeSample\">intLength = Len(strRunCommand)\nstrRunCommand = Left(strRunCommand, intLength &#8211; 2)\n<\/PRE>\n<P>If you look in the registry, you\u2019ll see that our commands all have a <B>\\1<\/B> appended to the end. We could leave that if we wanted to, but it\u2019s easy enough to get rid of. All we do is determine the length of the command, then use the <B>Left<\/B> function to return the first <I>x<\/I> characters in the string. And what is <I>x<\/I> equal to? It\u2019s equal to the total number of characters minus 2. That simply means we\u2019re going to grab all the characters except the last 2 (the \\1) and echo those to the screen.<\/P>\n<P>And there you have it: a script that returns the most-recently used commands typed into the <B>Run<\/B> dialog box. We still haven\u2019t figured out where that mysterious stairway leads, but first things first.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! Sometimes I type commands in the Run dialog box that I\u2019d like to retrieve later on. I know the most recent commands I used are cached somewhere; that\u2019s because they show up when I start typing in the Run dialog box. How can I use a script to retrieve these commands?&#8212; KJ [&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,31,26,3,5,226],"class_list":["post-67683","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-desktop-management","tag-operating-system","tag-registry","tag-scripting-guy","tag-vbscript","tag-windows-explorer"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! Sometimes I type commands in the Run dialog box that I\u2019d like to retrieve later on. I know the most recent commands I used are cached somewhere; that\u2019s because they show up when I start typing in the Run dialog box. How can I use a script to retrieve these commands?&#8212; KJ [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67683","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=67683"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/67683\/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=67683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=67683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=67683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}