how to get the original filedate not date modifyed lazarus / 67-Windows ---------------------------------------------------------------------- ratmalwer · 2017-11-07 12:13 Hello I have this statement witch works Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i FileDateTime := FormatDateTime('YYYY.MM.DD hh:mm:ss', FileDateToDateTime(FileAge(myFilename)));Result = 2015.08.14 20:15:48 When I check it with the Windows-Explorer I see that this result is the date-modified. How can I get the original-date of the file (created by my camara) witch is 2006.04.04 12:28 ??? ---------------------------------------------------------------------- ASerge · 2017-11-07 15:48 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows; function TryGetFileTimeCreated(const FileName: string; out Created: TDateTime): Boolean;var  R: TSearchRec;  UTCTime, LocalTime: TSystemTime;begin  Result := FindFirst(FileName, faArchive, R) = 0;  if Result then  begin    SysUtils.FindClose(R);    Result := FileTimeToSystemTime(@R.FindData.ftCreationTime, @UTCTime) and      SystemTimeToTzSpecificLocalTime(nil, @UTCTime, @LocalTime);  end;  if Result then    Created := SystemTimeToDateTime(LocalTime)  else    Created := 0;end; procedure TForm1.FormCreate(Sender: TObject);var  Created: TDateTime;begin  if TryGetFileTimeCreated(Application.ExeName, Created) then    Caption := DateTimeToStr(Created);end; ---------------------------------------------------------------------- ratmalwer · 2017-11-07 17:08 Hi Serge thanks for this clear funtion.... it works nicely but does not give me the desired result. As I do not have a Windowsversion in english I enclose the corresponding Printscreen. My solution gives the result shown in column B. (modificationtime = probabli when I resized the picture last) Your solution gives the result in column D (creationtime = the time I copied the picture). What I want is the time shown in Column A or C (the time th picture was taken).... ... somehow I suspect Windows looks at the EXIF of the picture when creating this Datetime. But I do not know where it is stored. ---------------------------------------------------------------------- molly · 2017-11-07 17:21 I haven't checked ASerge's code, but took my inspiration (read: shameless copy) from StackOverFlow. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; {$MODE OBJFPC}{$H+} uses  WIndows, SysUtils;  procedure ReportTime(const Name: string; const FileTime: TFileTime);var  SystemTime, LocalTime: TSystemTime;begin  if not FileTimeToSystemTime(FileTime, SystemTime)   then RaiseLastOSError;   if not SystemTimeToTzSpecificLocalTime(nil, SystemTime, LocalTime)   then RaiseLastOSError;  WriteLn(Name, ': ', DateTimeToStr(SystemTimeToDateTime(LocalTime)));end; procedure ReportFileTimes(const FileName: string);var  fad: TWin32FileAttributeData;begin  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad)   then RaiseLastOSError;  WriteLn(FileName);  ReportTime('Created' , fad.ftCreationTime);  ReportTime('Modified', fad.ftLastWriteTime);  ReportTime('Accessed', fad.ftLastAccessTime);end; begin  ReportFileTimes('test.exe');end.  Perhaps that is able to help you out ? ---------------------------------------------------------------------- ratmalwer · 2017-11-07 17:37 Thanks.. it looks similar to Serges code... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   ReportTime('Created' , fad.ftCreationTime);  ReportTime('Modified', fad.ftLastWriteTime);  ReportTime('Accessed', fad.ftLastAccessTime); here I need someting like (wherever Windows stores this)   ReportTime('original' , fad.ftOriginalTime); ???  ReportTime('EXIF', fad.ftEXIFTime);  ???  ReportTime('camera', fad.ftCameraTime); ??? ---------------------------------------------------------------------- molly · 2017-11-07 17:47 Ah ok. Just to make sure: are you are talking about metadata stored inside the file itself ? In case it is then this can't be retrieved with the functions showed so far. It depends on the fileformat and how the metadata is stored inside the file. Seeing that you mentioned exif, afaik means that you would either require to use a exif library that examines the file or use special windows shell api functionality (the latter i do not have a ready to go example for as ti depends on the installed explorer extension(s)). ---------------------------------------------------------------------- ratmalwer · 2017-11-07 18:01 You see my problem alright! But Windows stores this date in the field: date taken (rightclick on a JPG in explorer --- Properties -- Details  -- Title: Origin) and makes it to its (main)date.  -- or look at my printscreen above. Now is just the question how to get hold of that. ---------------------------------------------------------------------- ratmalwer · 2017-11-07 18:08 Hi molly again you are right... sorry I did not finish reading correctly. So if somebody has a API-solution I gladly apprechiate that. On the other hand I can redesign my workflow, as I'm not verry good in API-Calls and verry new to lazarus.. ---------------------------------------------------------------------- ratmalwer · 2017-11-07 22:42 Finally I fount the right property - it is System.Photo.DateTaken https://msdn.microsoft.com/en- us/library/windows/desktop/bb760410(v=vs.85).aspx but how do I implement an API-Call??? I did not find an example... ---------------------------------------------------------------------- molly · 2017-11-08 00:56 @ratmalwer: You can try the port of DExif library, which afaik has the additional feature of being platform agnostic. If you download the sources then there is a pdf that has all relevant information listed to tell you how to use the library. ---------------------------------------------------------------------- ratmalwer · 2017-11-08 12:22 Thanks for this hint. This could be a possibility, but I suppose it is rather slow on a big amount of pictures. Now I installed the package: DExif and got the basic-example running - I get a heap-error closing the app. So I have no plan what to do?! Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button1Click(Sender: TObject);var  MyFileName : String;  ImgData: TImgData;begin     if OpenDialog1.Execute then   begin     MyFileName := OpenDialog1.Filename;   end;  if FileExists(MyFileName) then begin    ValueListEditor1.Clear;    Image1.Proportional:= True;  Image1.Stretch:= True;    Image1.Picture.LoadFromFile(MyFileName);  ImgData:= TImgData.Create();    try      if ImgData.ProcessFile(MyFileName) then begin        if ImgData.HasEXIF then begin          ValueListEditor1.InsertRow('Camera Make',          ImgData.ExifObj.CameraMake,True);          ValueListEditor1.InsertRow('Camera Modell',            ImgData.ExifObj.CameraModel,True);          ValueListEditor1.InsertRow('Picture DateTime',            FormatDateTime(ISO_DATETIME_FORMAT, ImgData.ExifObj.GetImgDateTime),True);        end        else        ValueListEditor1.InsertRow('No EXIF','No Data',True);      end      else        ValueListEditor1.InsertRow('No EXIF','Processdata',True);    finally      ImgData.Free;    end;  end;end; ---------------------------------------------------------------------- molly · 2017-11-09 01:11 Quote from: ratmalwer on November 08, 2017, 01:22:34 pmThanks for this hint. This could be a possibility, but I suppose it is rather slow on a big amount of pictures. How do you think that Explorer retrieves this information ? Exactly in a similar manner  The only thing that explorer could perhaps do better (due to its integration) is caching the results in the background. That advantage is gone the moment you start to handle a big amount of files, as cache runs dry. QuoteNow I installed the package: DExif and got the basic-example running - I get a heap-error closing the app. So I have no plan what to do?! Post your project or create a simple example project showing that heaptrace error. You can publish your project inside lazarus and zip up the directory/files where you published the files into. You can attach that zip-file to a post on the forum I made a simple example using FPC, based on the code you showed and i did not experience any leakage. That suggests that you have some leakage somewhere else inside your code and is probably not related to your use of DExif library. fwiw: this is the output from my fpc test example (using the nokia test jpg that came with DExif): Code: [Select]> test Camera Make      : Nokia Camera Model     : 6300 Picture DateTime : 2017-09-11 09:57:02 Heap dump by heaptrc unit 1559 memory blocks allocated : 141850/158056 1559 memory blocks freed     : 141850/158056 0 unfreed memory blocks : 0 True heap size : 163840 (96 used in System startup) True free heap : 163744 Note that heaptrace does produce a message (i did not turned that off), but is telling that there are zero unfreed memory blocks (meaning everything went ok). ---------------------------------------------------------------------- ratmalwer · 2017-11-09 13:51 Hi molly thanks that you care. I agree, that windows gets the information from the Exif. But I think it stores it in System.Photo.DateTaken for fast access in Windows- explorer. Else it would take ages opening a folder contining hundreds of pictures. Thats the reason I fancy this option. On the other hand I could use the DExif to display more information in my app. So I enclose my project (Basic-sample sligtly modifyed) and the errormessage. Please tell me if thats suffitient. ---------------------------------------------------------------------- molly · 2017-11-09 16:02 Quote from: ratmalwer on November 09, 2017, 02:51:10 pmthanks that you care. Please tell me if thats suffitient. You're welcome, and at the same time you make my 'job' easy. The picture alone was sufficient  Take a very good look at your screen-shot. It says: "0 unfreed memory blocks : 0" As i wrote in my previous post, that means that everything went ok. There are no memory leaks in your project. You might ask yourself then why on earth does heaptrace display a message when there are no leaks. The answer to that is simple: You either make use of heaptrace or you don't. By default heaptrace outputs its collected information. You can change that behaviour by setting the variable GlobalSkipIfNoLeaks to true on your program startup (form.create should be ok). afair it might be that you have a Lazarus with an older FPC compiler, in which case this variable is not available (so that you are unable to influence this behaviour of heaptrace). What you could  do then is opt for upgrading your Lazarus installation. ---------------------------------------------------------------------- mai · 2017-11-09 18:51 maybe use statx xstat (search my other post) make syscall to use it ---------------------------------------------------------------------- ASerge · 2017-11-09 21:58 Quote from: ratmalwer on November 07, 2017, 07:01:28 pmBut Windows stores this date in the field: date taken (rightclick on a JPG in explorer --- Properties -- Details  -- Title: Origin) and makes it to its (main)date.  -- or look at my printscreen above. Get any property from the shell! Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$APPTYPE CONSOLE}program Project1; uses Windows, SysUtils, ActiveX, ShlObj; function GetShellFolder2(const Dir: UnicodeString; out Intf: IShellFolder2): Boolean;var  DesktopFolder: IShellFolder;  DirPIDL: PItemIDList = nil;begin  Result := Succeeded(SHGetDesktopFolder(DesktopFolder)) and    Succeeded(DesktopFolder.ParseDisplayName(0, nil, PWideChar(Dir),      ULONG(nil^), DirPIDL, ULONG(nil^))) and    Succeeded(DesktopFolder.BindToObject(DirPIDL, nil, IID_IShellFolder2, Intf));  CoTaskMemFree(DirPIDL);end; function GetFileProperty(const FileName: string; const Column: SHColumnID;  out Value: OleVariant): Boolean;var  DirFolder: IShellFolder2;  FilePIDL: PItemIDList = nil;  WFileName: UnicodeString;begin  WFileName := Utf8Decode(FileName);  Result := False;  if GetShellFolder2(ExtractFileDir(WFileName), DirFolder) then  begin    Result := Succeeded(DirFolder.ParseDisplayName(0, nil,      PWideChar(ExtractFileName(WFileName)),        ULONG(nil^), FilePIDL, ULONG(nil^))) and      Succeeded(DirFolder.GetDetailsEx(FilePIDL, Column, @Value));    CoTaskMemFree(FilePIDL);  end;end; const  CFileName = 'c:\Path\Your favorite file.JPG';  // All available values see in propkey.h in SDK  CColumnPhotoDateTaken: SHColumnID = ( // PKEY_Photo_DateTaken    fmtid: '{14B81DA1-0135-4D31-96D9-6CBFC9671A99}'; // FMTID_ImageProperties    pid: 36867);var  Value: OleVariant;begin  CoInitialize(nil);  if GetFileProperty(CFileName, CColumnPhotoDateTaken, Value) then  begin  Writeln('Photo Date Taken at UTC: ', Value);  end;  Readln;end. ---------------------------------------------------------------------- ratmalwer · 2017-11-09 23:01 hello molly you where right GlobalSkipIfNoLeaks is not known by lazarus-1.6.4-fpc-3.0.2-win64.exe. Even it is the latest Version on official Lazarus-Site. So I searched the net and found: Lazarus-1.8  RC5  (i did not try) Lazarus-1.9-56259_fpc-3.1.1-37548M_20171103-1327.7z (google)  -> this i unzipped and messed up my installation. (compiler missing and so on...) Now I just removed my installation. So how do I get a installation that is up to date? Or is there one coming on official site soon? ---------------------------------------------------------------------- ratmalwer · 2017-11-09 23:04 hi mai i just found this one: Linux / Re: new kernel function fstatx() in Kern 4.11 Can you be a little more specific - Im rather new at Lazarus and pascal and working with Windows 7. ---------------------------------------------------------------------- molly · 2017-11-09 23:35 Quote from: ratmalwer on November 10, 2017, 12:01:06 amhello molly you where right GlobalSkipIfNoLeaks is not known by lazarus-1.6.4-fpc-3.0.2-win64.exe. Eh... that's weird  FPC 3.0.2 should be enough (i use that version as well). QuoteSo how do I get a installation that is up to date? Or is there one coming on official site soon? The 1.8 release should become a final release pretty soon. But somehow everything related to this release seems to be a bit ... well ... out of the ordinary. So, please don't hold that against me in case it will take another year before reaching final release You should be good to go with your initial installation of lazarus-1.6.4-fpc-3.0.2-win64.exe. I would recommend to verify this with someone else first as i'm unable to verify myself at the moment. I apologize for recommending to upgrade. I more or less expected that you would mention your current version first, before actually performing an upgrade. In hindsight that seem to have caused more trouble than you bargained for  Are you able to remove your current installation and re-install lazarus-1.6.4-fpc-3.0.2-win64.exe ? If not then please feel free to mention the errors you are encountering, so that we're able to solve them for you. ---------------------------------------------------------------------- ratmalwer · 2017-11-10 02:18 HEUREKA ... I found it.... I placed the directive in the project as shown.... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program BaseSample; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}{$IFDEF UseCThreads}  cthreads,  {$ENDIF}{$ENDIF}  Interfaces, // this includes the LCL widgetset  Forms, ureadexif  { you can add units after this }; {$R *.res} begin  RequireDerivedFormResource:=True;  Application.Initialize;  Application.CreateForm(TForm1, Form1);  Application.Run;  GlobalSkipIfNoLeaks := true;  UseHeapTrace := false;end. still hoping to get an examle of some (any) API-Call to windows and where to place it, so I could try to get the datetaken property of windows (I am still a newbee but try to improove) ---------------------------------------------------------------------- molly · 2017-11-10 02:57 Quote from: ratmalwer on November 10, 2017, 03:18:08 amHEUREKA Glad that you was able to find it. Quotestill hoping to get an examle of some (any) API-Call to windows and where to place it, so I could try to get the datetaken property of windows Look at reply #15 from ASerge. That is using activeX shell object api to retrieve the (column) information. ---------------------------------------------------------------------- ratmalwer · 2017-11-10 04:15 Thanks all for your help.... Reading though the web and asking on other platforms it seems I am wrong with my oppinion that the datetaken is a property witch can be accessed directly by API / NTFS... In other words, it ist actually needed to open each file to get its Exif... as I was told earlyer... so i declare this thead as closed.... ---------------------------------------------------------------------- Mike.Cornflake · 2017-11-11 19:33 Last time I read EXIF I was a Delphi programmer.  Back then I used the dEXIF library which I was quite happy with.  Looking around I see this has been translated to Lazarus... https://github.com/cutec-chris/dexif ---------------------------------------------------------------------- JuhaManninen · 2017-11-11 21:22 Quote from: Mike.Cornflake on November 11, 2017, 08:33:24 pmhttps://github.com/cutec-chris/dexif The ReadMe says the license was switched to LGPL with author's permission. The Copyright.txt however explains a very different license. Somebody should tell them to update it. ---------------------------------------------------------------------- Mike.Cornflake · 2017-11-11 21:28 At the top of Copyright.txt Quote---------------------------------- This port of dEXIF to Lazarus/Freepascal is accepted in July 2017 by the Copyright-Owner ---------------------------------- Hello Andreas ,   It is possible, all I ask is attribution somewhere in your documentation or source.    I will indeed look at updating the license terms but wanted to let you know it's OK to proceed so you don't have to wait. Thanks,  Gerry McGuire dEXIF author. --------------------------------- So, it looks like Gerry is aware of this and updating the license is already on his TODO.