{"id":65793,"date":"2007-01-05T06:29:00","date_gmt":"2007-01-05T06:29:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/01\/05\/hey-scripting-guy-how-can-i-get-the-date-picture-taken-property-from-a-jpg-file\/"},"modified":"2007-01-05T06:29:00","modified_gmt":"2007-01-05T06:29:00","slug":"hey-scripting-guy-how-can-i-get-the-date-picture-taken-property-from-a-jpg-file","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-get-the-date-picture-taken-property-from-a-jpg-file\/","title":{"rendered":"Hey, Scripting Guy! How Can I Get the \u201cDate Picture Taken\u201d Property From a .JPG File?"},"content":{"rendered":"<h2><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" class=\"nearGraphic\" \/> <\/h2>\n<p>Hey, Scripting Guy! How can I get the <b>Date Picture Taken<\/b> property from a .JPG file?<\/p>\n<p>&#8212; MW<\/p>\n<p><img decoding=\"async\" height=\"5\" width=\"5\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" alt=\"Spacer\" border=\"0\" \/><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" class=\"nearGraphic\" \/><a href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><\/a><\/p>\n<p>Hey, MW. Before we answer your question we should point out that this is likely to be the last <i>Hey, Scripting Guy!<\/i> column for quite some time to come. Not that we&rsquo;re going anywhere, mind you. It&rsquo;s just that on Saturday, the Seattle Seahawks will host the Dallas Cowboys in a nationally-televised football game. And that&rsquo;s a problem. Early in December the Seahawks hosted Green Bay in a nationally-televised game and the Seattle area was promptly hit with a freak ice storm that shut the city down for two days. Shortly before Christmas the Seahawks hosted the San Francisco 49ers in a nationally-televised game. That same evening a &ldquo;once-in-a-century&rdquo; windstorm ripped through the region, and, among other things, the Scripting Guy who writes this column lost electricity for 6 long, cold days. Granted, the odds suggest that nothing that bad could <i>possibly<\/i> happen again. Nevertheless, the Scripting Guy who writes this column has been building an ark in his back yard, just in case. All he has to do now is round up two of every kind of animal and he&rsquo;ll be in business.<\/p>\n<p>Of course, as long as we have a little time before the next disaster strikes we might as well see if we can find a solution for you. Admittedly, a month or so ago we could have answered this question without any problem: &ldquo;Sorry, MW, but there&rsquo;s no way to get at that information, at least not by using a script.&rdquo; However, that was before Microsoft released <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/desktop\/wdsearch.mspx\"><b>Windows <\/b><b>Desktop Search 3.0<\/b><\/a>. As it turns out, now there <i>is<\/i> a way to use a script to determine the date a digital photo was taken:<\/p>\n<pre class=\"codeSample\">Set objConnection = CreateObject(\"ADODB.Connection\")<br \/>Set objRecordSet = CreateObject(\"ADODB.Recordset\")<\/pre>\n<pre class=\"codeSample\">objConnection.Open \"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';\"<\/pre>\n<pre class=\"codeSample\">objRecordSet.Open \"SELECT System.FileName, System.Photo.DateTaken FROM SYSTEMINDEX \" &amp; _<br \/>    \"Where System.ItemFolderPathDisplay = 'D:\\Europe' and System.FileExtension = '.jpg'\", _ <br \/>   objConnection<\/pre>\n<pre class=\"codeSample\">objRecordSet.MoveFirs<\/pre>\n<pre class=\"codeSample\">tDo Until objRecordset.EOF<br \/>    Wscript.Echo objRecordset.Fields.Item(\"System.FileName\"), _<br \/>        objRecordset.Fields.Item(\"System.Photo.DateTaken\")<br \/>    objRecordset.MoveNext<br \/>Loop<\/pre>\n<p>A few caveats before we explain how this script works. First and foremost, this solution does require you to install Windows Desktop Search 3.0; you can get more information on how to do that <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/desktop\/wdsearch.mspx\"><b>here<\/b><\/a>. But that&rsquo;s not a bad thing: setup is quick and easy, and Desktop Search 3.0 has all sorts of cool uses beyond determining the date a digital photo was taken. Second, this solution works only on Windows XP, Windows Server 2003, and Windows Vista; that&rsquo;s because Desktop Search 3.0 is only available on those platforms. Will that change in the future? To be honest, we don&rsquo;t know. But we hope so, because this really is a nice little technology.<\/p>\n<p>As for the script itself, we start out by creating two objects: <b>ADODB.Connection<\/b> and <b>ADODB.Recordset<\/b>. If these names ring a bell, well, that&rsquo;s not surprising: these are the two fundamental objects used with ActiveX Data Objects (ADO), the scripting technology that lets you connect to and work with such disparate data sources as <a target=\"_blank\" href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dnclinic\/html\/scripting03092004.asp\"><b>text files<\/b><\/a>, <a target=\"_blank\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=25562\"><b>Active Directory<\/b><\/a>, and, of course, <a target=\"_blank\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=22089\"><b>databases<\/b><\/a>. That&rsquo;s one of the things we really like about Desktop Search 3.0: if you know how to write ADO scripts then you pretty much know how to write Desktop Search scripts as well.<\/p>\n<p>After creating the Connection and Recordset objects we use the <b>Open<\/b> method to make a connection to the Desktop Search data store. Don&rsquo;t worry about the details of this code; just consider it boilerplate text that you can paste in any time you want to use Desktop Search 3.0:<\/p>\n<pre class=\"codeSample\">objConnection.Open \"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';\"<\/pre>\n<p>Once we make the connection we then use the following code to return the <b>FileName<\/b> and <b>DateTaken<\/b> properties for all the .JPG files found in the folder D:\\Europe:<\/p>\n<pre class=\"codeSample\">objRecordSet.Open \"SELECT System.FileName, System.Photo.DateTaken FROM SYSTEMINDEX \" &amp; _<br \/>    \"Where System.ItemFolderPathDisplay = 'D:\\Europe' and System.FileExtension = '.jpg'\", _<br \/>    objConnection<\/pre>\n<p>And, sure, we could easily return this information for a single file, or for all the .JPG files on the computer. (Wouldn&rsquo;t <i>that<\/i> script take forever to run? Obviously you haven&rsquo;t tried Desktop Search 3.0, have you?) For more information on writing queries for Desktop Search 3.0 see our article <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/desktop\/wdsearch.mspx\"><b>Seek and Ye Shall Find<\/b><\/a>. For now, simply note that we&rsquo;re using a basic SQL statement that retrieves two property values (System.FileName and System.Photo.DateTaken) from the SYSTEMINDEX data store (the only data store available when using Desktop Search). Likewise, note the Where clause, which limits returned data to items found in the folder D:\\Europe (that is, items where the <b>ItemFolderPathDisplay<\/b> is equal to <i>D:\\Europe<\/i>) <i>and<\/i> have a <b>FileExtension<\/b> equal to <i>.jpg<\/i>. <\/p>\n<p>And yes, unlike WMI you <i>do<\/i> need to include the dot as part of the file extension.<\/p>\n<p>When we execute the <b>Open<\/b> method Desktop Search returns a recordset containing all the .JPG files found in the folder D:\\Europe (just like we asked it to). All we have to do at that point is set up a Do Until loop that loops through that recordset (that is, that runs until the recordset&rsquo;s <b>EOF<\/b> &ndash; End-of-File &ndash; property is True). Inside that loop we simply echo back the file name and the date the picture was taken; we then use the <b>MoveNext<\/b> method to move to the next item in the recordset and echo back that same information. That block of code looks like this:<\/p>\n<pre class=\"codeSample\">Do Until objRecordset.EOF<br \/>    Wscript.Echo objRecordset.Fields.Item(\"System.FileName\"), _<br \/>        objRecordset.Fields.Item(\"System.Photo.DateTaken\")<br \/>    objRecordset.MoveNextLoop<\/pre>\n<p>And that&rsquo;s all we have to do. When we run the script, we should get back information similar to this:<\/p>\n<pre class=\"codeSample\">europe001.jpg 8\/16\/2005 11:22:30 AM<br \/>europe002.jpg 8\/16\/2005 11:22:49 AM<br \/>europe003.jpg 8\/16\/2005 11:23:02 AM<br \/>europe004.jpg 8\/16\/2005 11:24:41 AM<br \/>europe005.jpg 8\/16\/2005 11:25:14 AM<\/pre>\n<p>Best of all, we get this information back in just a few seconds. <i>Very<\/i> cool.<\/p>\n<p>So are the Scripting Guys getting nervous as we get closer and closer to game time? No, not really. After all, Microsoft would never let anything happen to its most-valued employees; therefore, we simply plan on watching the game with <i>those<\/i> guys. <\/p>\n<table cellpadding=\"0\" cellspacing=\"0\" class=\"dataTable\" id=\"E2G\">\n<thead><\/thead>\n<tbody>\n<tr valign=\"top\" class=\"record\">\n<td>\n<p class=\"lastInCell\"><b>Note<\/b>. On the bright side, come hell or high water (neither of which would surprise us at this point) this will be the last home game for the Seahawks this year. Thank goodness they were so mediocre this season!<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I get the Date Picture Taken property from a .JPG file? &#8212; MW Hey, MW. Before we answer your question we should point out that this is likely to be the last Hey, Scripting Guy! column for quite some time to come. Not that we&rsquo;re going anywhere, mind you. It&rsquo;s [&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":[122,123,3,5],"class_list":["post-65793","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-graphics","tag-multimedia","tag-scripting-guy","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I get the Date Picture Taken property from a .JPG file? &#8212; MW Hey, MW. Before we answer your question we should point out that this is likely to be the last Hey, Scripting Guy! column for quite some time to come. Not that we&rsquo;re going anywhere, mind you. It&rsquo;s [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65793","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=65793"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/65793\/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=65793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=65793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=65793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}