{"id":63523,"date":"2007-11-27T00:51:00","date_gmt":"2007-11-27T00:51:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/11\/27\/hey-scripting-guy-how-can-i-randomly-assign-a-picture-from-the-my-pictures-folder-as-the-computer-wallpaper\/"},"modified":"2007-11-27T00:51:00","modified_gmt":"2007-11-27T00:51:00","slug":"hey-scripting-guy-how-can-i-randomly-assign-a-picture-from-the-my-pictures-folder-as-the-computer-wallpaper","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-randomly-assign-a-picture-from-the-my-pictures-folder-as-the-computer-wallpaper\/","title":{"rendered":"Hey, Scripting Guy! How Can I Randomly Assign a Picture From the My Pictures Folder as the Computer Wallpaper?"},"content":{"rendered":"<p><H2><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\"> <\/H2>\n<P>Hey, Scripting Guy! I saw <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jan07\/hey0118.mspx\"><B>your column<\/B><\/A> on randomly assigning a picture to use as the wallpaper on a computer. I\u2019d like to do the same thing, except that, instead of picking from a predefined list of pictures, I\u2019d like to randomly assign a picture from the user\u2019s My Pictures folder. How do I do that?<BR><BR>&#8212; JJ<\/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, JJ. You know, this has been a crazy month for the Scripting Guys. When the month began, we were absolutely <I>swamped<\/I> trying to get everything in place for our trip to Barcelona and <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/teched07\/eu.mspx\"><B>TechEd IT Forum<\/B><\/A>. (Not being the brightest of Microsoft employees, the Scripting Guys actually did more work during their \u201cvacation\u201d in Spain than they do in a normal week.) After being gone for 9 days we returned home just in time for Thanksgiving; in fact, the Scripting Editor didn\u2019t even bother to come in for those three days before Thanksgiving.<\/P>\n<TABLE id=\"ELD\" 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>. You know, you\u2019d be amazed at how many people have said that very same thing. And you\u2019re right: things <I>did<\/I> seem to go incredibly well during her absence, didn\u2019t they?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Now, however, the party\u2019s over (well, at least until Christmas, which is rapidly approaching). Among other things, that means it\u2019s time to get back to work, and time to start tying up a few loose ends. For example, we\u2019ve hardly had the chance to mention the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/teched07\/itchallenge.mspx\"><B>IT Forum Challenge<\/B><\/A> currently going on in the Script Center. Not only is this a fun little contest, but it\u2019s also your absolute <I>last<\/I> chance to win a Dr. Scripto bobblehead doll: we are down to our last precious few bobbleheads. (No, that doesn\u2019t include the Scripting Editor. We said our <I>precious<\/I> bobbleheads.)<\/P>\n<TABLE id=\"EHE\" 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>. Yes, it <I>is<\/I> fun when the Scripting Editor doesn\u2019t come in to work, isn\u2019t it? Let\u2019s just hope she forgets to look at this column when she does come back. What do you say we keep this one as our little secret?<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Anyway, we encourage everyone to take a crack at the Challenge; like they say, <I>someone<\/I> has to win. (Who says that? Our legal department, which won\u2019t let us hold a contest unless we actually give away the prizes. Which explains why we\u2019ve never bothered to give away a new Porsche or BMW; after all, we\u2019d have to actually <I>give the thing away<\/I>.) And for those of you who\u2019ve been asking, yes, we\u2019ll post a list of the leading scores sometime this week. We had planned to do that while we were in Barcelona but the network connectivity between our hotel and Microsoft was a bit slow, to say the least. (You\u2019d think by now they could breed carrier pigeons that could fly a little faster, but apparently they can\u2019t.)<\/P>\n<P>So what other loose ends do we have to tie up? Well, here\u2019s one: someone out there needs a script that can randomly grab a picture from a user\u2019s My Pictures folder and then assign that picture as the user\u2019s wallpaper. Fortunately for us, we just happened to have a script like that lying around:<\/P><PRE class=\"codeSample\">Const MY_PICTURES = &amp;H27&amp;\nConst HKEY_CURRENT_USER = &amp;H80000001<\/p>\n<p>Set objDictionary = CreateObject(&#8220;Scripting.Dictionary&#8221;)<\/p>\n<p>Set objShell = CreateObject(&#8220;Shell.Application&#8221;)\nSet objFolder = objShell.Namespace(MY_PICTURES) \nSet objFolderItem = objFolder.Self   <\/p>\n<p>strPath = objFolderItem.Path<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFolder = objFSO.GetFolder(strPath)\nSet colFiles = objFolder.Files<\/p>\n<p>i = 0<\/p>\n<p>For Each objFile in colFiles\n    i = i + 1\n    objDictionary.Add i, objFile.Path\nNext<\/p>\n<p>intHighNumber = objDictionary.Count\nintLowNumber = 1<\/p>\n<p>Randomize\nintNumber = Int((intHighNumber &#8211; intLowNumber + 1) * Rnd + intLowNumber)<\/p>\n<p>strPicture = objDictionary.Item(intNumber)   <\/p>\n<p>strKeyPath = &#8220;Control Panel\\Desktop&#8221;\nValueName = &#8220;Wallpaper&#8221;<\/p>\n<p>strComputer = &#8220;.&#8221;<\/p>\n<p>Set objReg = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\default:StdRegProv&#8221;)<\/p>\n<p>objReg.SetStringValue HKEY_USERS, strKeyPath, ValueName, strPicture\n<\/PRE>\n<P>Got all that? Good, because now for the fun part: figuring out what this hunk of code actually does, and how it does it. As you can see, we start out by defining a pair of constants, MY_PICTURES (which tells the script which special folder we want to work with), and HKEY_CURRENT_USER (which tells the script which registry hive we want to work with). After we define the two constants, we then use this line of code to create an instance of the <B>Scripting.Dictionary<\/B> object:<\/P><PRE class=\"codeSample\">Set objDictionary = CreateObject(&#8220;Scripting.Dictionary&#8221;)\n<\/PRE>\n<P>Why did we create an instance of the Dictionary object? Good question and, to be honest, we didn\u2019t <I>have<\/I> to go this route; there are other ways that we could have tackled this problem. In the end, however, we decided that this was a reasonable approach: we\u2019ll grab the paths for all the files in the My Pictures folder and add them to the Dictionary. After we\u2019ve done that we\u2019ll generate a random number between 1 and the number of items in the Dictionary (that is, the number of files in the folder); for the moment, we\u2019ll assume we generated the random number 13. We\u2019ll then grab item 13 out of the Dictionary. Voila: we\u2019ve randomly selected a file from the My Pictures folder, and gotten hold of the file path to boot.<\/P>\n<P>Make sense? It <I>does<\/I>? <\/P>\n<P>Wow. After four years something we said actually made sense. Apparently all that practice is beginning to pay off.<\/P>\n<P>Our next chore is to determine the location of the user\u2019s My Picture folder. That\u2019s what this block of code does:<\/P><PRE class=\"codeSample\">Set objShell = CreateObject(&#8220;Shell.Application&#8221;)\nSet objFolder = objShell.Namespace(MY_PICTURES) \nSet objFolderItem = objFolder.Self   <\/p>\n<p>strPath = objFolderItem.Path\n<\/PRE>\n<P>Granted, this is a little goofy-looking. However, all we\u2019re doing here is creating an instance of the <B>Shell.Application<\/B> object and then using the <B>Namespace<\/B> method to bind to the My Pictures folder (notice that we pass this method the constant MY_PICTURES). Of course, in the mysterious world of the Shell object binding to a folder using the Namespace method is only half the battle; to actually be able to do retrieve information from that folder you need to then reference the <B>Self<\/B> property, which returns a FolderItem pointing to that folder. (OK, admittedly, that <I>doesn\u2019t<\/I> make a lot of sense. But that\u2019s not our fault, that\u2019s how the Shell object works.) This line of code returns a FolderItem object for the My Pictures folder:<\/P><PRE class=\"codeSample\">Set objFolderItem = objFolder.Self\n<\/PRE>\n<P>At least line 4 makes sense; in that line we simply grab the value of the folder\u2019s <B>Path<\/B> property and store it in a variable named strPath:<\/P><PRE class=\"codeSample\">strPath = objFolderItem.Path\n<\/PRE>\n<P>As soon as we know the path to the My Pictures folder we can go ahead and retrieve a collection of all the files in that folder. That\u2019s what this block of code is for:<\/P><PRE class=\"codeSample\">Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)\nSet objFolder = objFSO.GetFolder(strPath)\nSet colFiles = objFolder.Files\n<\/PRE>\n<P>These lines of code should be a little easier to follow. In lines 1 and 2, we create an instance of the <B>Scripting.FileSystemObject<\/B>, then use the <B>GetFolder<\/B> method to bind to the My Pictures folder. (How do we know that we\u2019re binding to the My Pictures folder? Because we pass GetFolder the variable strPath, which contains the path to that folder.) We then use this line of code to return a collection of all the files found in that folder:<\/P><PRE class=\"codeSample\">Set colFiles = objFolder.Files\n<\/PRE>\n<P>Admittedly, the whole thing is a tad-bit cumbersome. But it works: we now have a collection of all the files in My Pictures.<\/P>\n<P>And just exactly what are we going to <I>do<\/I> with that collection? Well, first of all, we\u2019re going to assign the value 0 to a counter variable named<\/P><PRE class=\"codeSample\">i = 0\n<\/PRE>\n<P>And then we\u2019re going to use this block of code to loop through the collection of files:<\/P><PRE class=\"codeSample\">For Each objFile in colFiles\n    i = i + 1\n    objDictionary.Add i, objFile.Path\nNext\n<\/PRE>\n<P>As you can see, inside that loop the first thing we do is increment the value of i by 1. We then call the <B>Add<\/B> method to add the file to the Dictionary, using the counter variable i as the Dictionary key and the value of the file\u2019s <B>Path<\/B> property as the Dictionary item:<\/P><PRE class=\"codeSample\">objDictionary.Add i, objFile.Path\n<\/PRE>\n<TABLE id=\"EEH\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P><B>Note<\/B>. Dictionary key? Dictionary item? You say you have no idea what those terms even <I>mean<\/I>? In that case, you might want to take a peek at <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/begin\/ss0906.mspx\"><B>this edition<\/B><\/A> of <I>Sesame Script<\/I>, everyone\u2019s favorite scripting column.<\/P>\n<P>Well, you\u2019re right: everyone\u2019s <I>second<\/I>-favorite scripting column. We were just being modest.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>When we\u2019re all done, our Dictionary will contain information similar to this:<\/P>\n<TABLE id=\"ECAAC\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Key<\/B><\/P><\/TD>\n<TD>\n<P class=\"lastInCell\"><B>Item<\/B><\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">1<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">C:\\Documents and Settings\\kenmyer\\My Documents\\My Pictures\\Picture1.jpg<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">2<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">C:\\Documents and Settings\\kenmyer\\My Documents\\My Pictures\\Picture2.jpg<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\">3<\/P><\/TD>\n<TD>\n<P class=\"lastInCell\">C:\\Documents and Settings\\kenmyer\\My Documents\\My Pictures\\Picture3.jpg<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>We should note that we\u2019re assuming that the <I>only<\/I> files stored in My Pictures are picture files. If that\u2019s not true you\u2019ll need to include code that makes sure you\u2019re dealing with a picture before you add that file to the Dictionary. How could you do that? Well, without going into any detail, here\u2019s a modified For Each loop that uses the <B>GetExtensionName<\/B> method to retrieve the file extension for each file, then adds that file to the Dictionary only if the file extension is JPG, BMP, or GIF:<\/P><PRE class=\"codeSample\">For Each objFile in colFiles\n    strExtension = objFSO.GetExtensionName(objFile.Path)\n    If strExtension = &#8220;jpg&#8221; or strExtension = &#8220;bmp&#8221; or strextension = &#8220;gif&#8221; Then\n        Wscript.Echo strExtension\n        i = i + 1\n        objDictionary.Add i, objFile.Path\n    End If\nNext\n<\/PRE>\n<P>Now we\u2019re ready to have some fun. To begin with, we use this line of code to assign the total number of files in the Dictionary (the <B>Count<\/B> property) to a variable named intHighNumber:<\/P><PRE class=\"codeSample\">intHighNumber = objDictionary.Count\n<\/PRE>\n<P>After that, we assign the value 1 to a variable named intLowNumber; from there we can use these two lines of code to generate a random number between 1 (intLowNumber) and the total number of files in the Dictionary (intHighNumber):<\/P><PRE class=\"codeSample\">Randomize\nintNumber = Int((intHighNumber &#8211; intLowNumber + 1) * Rnd + intLowNumber)\n<\/PRE>\n<P>As you can see, the random number we generate gets stored in a variable named intNumber. Again, let\u2019s say that intNumber is 13. That means we want to use picture number 13 as our wallpaper. How do we retrieve the path for picture number 13? That\u2019s easy: we just return the Item value for the Dictionary element that has a key equal to 13:<\/P><PRE class=\"codeSample\">strPicture = objDictionary.Item(intNumber)\n<\/PRE>\n<P>All we do is pass the Dictionary object the appropriate key (intNumber) and the value of that particular item (which happens to be a file path) is assigned to a variable named strPicture.<\/P>\n<P>From there we simply use a little WMI magic (and the <B>StdRegProv<\/B> class) to write the new wallpaper path to the registry. We won\u2019t discuss that process in any detail today; for more information, see <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jan07\/hey0118.mspx\"><B>our previous column<\/B><\/A> on randomly assigning wallpaper to a computer.<\/P>\n<P>Two things to keep in mind here. First, this script is designed to run only on the local computer. Could it be modified to work against a remote computer? Well, probably, although ferreting out the location of the My Pictures folder would be a bit of a chore. For now, assume this is local computer only. But that\u2019s OK, because this is intended to be used as a logoff script anyway.<\/P>\n<P>That, by the way, is point number 2. Could you use this as a <I>logon<\/I> script? Sure, except that the wallpaper change won\u2019t take effect until the user logs off and then logs back on: changing the wallpaper value in the registry does <I>not<\/I> cause the desktop to refresh and display that new wallpaper. There are various hacks and workarounds that <I>sometimes<\/I> seem to work in this regard, but we\u2019re not really in a position to recommend any of them. You can search the Internet and try one of these approaches (at your own risk, mind you). Or, just use this as a log<I>off<\/I> script instead.<\/P>\n<P>We hope that answers your question, JJ. In the meantime, the Scripting Guy who writes this column has a ton of other loose ends to tie up, all of them of the highest priority and all of them which must be dealt with immediately<\/P>\n<P>And all of which he will do his darnedest to get to. Right after lunch.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I saw your column on randomly assigning a picture to use as the wallpaper on a computer. I\u2019d like to do the same thing, except that, instead of picking from a predefined list of pictures, I\u2019d like to randomly assign a picture from the user\u2019s My Pictures folder. How do I do [&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,47,3,5],"class_list":["post-63523","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-desktop-management","tag-general-management-tasks","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I saw your column on randomly assigning a picture to use as the wallpaper on a computer. I\u2019d like to do the same thing, except that, instead of picking from a predefined list of pictures, I\u2019d like to randomly assign a picture from the user\u2019s My Pictures folder. How do I do [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63523","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=63523"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/63523\/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=63523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=63523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=63523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}