Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Compilierdatum (https://www.delphipraxis.net/11654-compilierdatum.html)

Delphianer 11. Nov 2003 12:58


Compilierdatum
 
Hallo,

was ich schon lange suche und noch nie gefunden habe:

Legt der Delphi-Compiler irgendwo in der Exe das Datum des Compilierens ab? Das Datum der Exe nützt mir dabei nichts, das kann man ändern. Automatisch hineincompilieren geht auch, mir wäre aber eine 'eingebaute' Lösung lieber.

Danke und viele Grüße!

choose 11. Nov 2003 13:10

Re: Compilierdatum
 
Hallo Delphianer,

für das Datum fällt mir ad hoc keine Lösung ein, aber vielleicht hilf Dir die Suche nach Hier im Forum suchenversionsinfo weiter?

Delphianer 11. Nov 2003 13:37

Re: Compilierdatum
 
Danke,

aber das ist es nicht. Ich suche etwas, was Delphi automatisch einträgt.

choose 11. Nov 2003 14:04

Re: Compilierdatum
 
Delphi ist in der Lage, die Versionsnummer bei jedem Build automatisch zu inkrementieren.
Oder muss es unbedingt das Datum sein?

Delphianer 11. Nov 2003 14:11

Re: Compilierdatum
 
Ja, ich suche das Compilierdatum, von Delphi höchstselbst eingetragen. Aus irgendeinem Grund scheinen das die Delphi-Entwickler aber nicht vorgesehen zu haben, oder?

negaH 11. Nov 2003 16:21

Re: Compilierdatum
 
Normalerweise sollte das Compilierungsdatum und die EXE Prüfsumme im PE Fileheader der EXE stehen. Aber, was ist schon normal ? denn der Delphi Compiler legt da seinen eigenen Magic-Mist rein. Die CRC berechnet er garnicht.
Nungut, es gibt aber einen Weg. Der Linker von Delphi erzeugt die EXE aus den Code-/Daten- und Resourcesegementen. Jedesmal wenn du compilierst linkt er also die Resourcen in die EXE neu rein. Es sind immer Resourcen vorhanden. Eine Resource hat ein Erstellungsdatum und dieses ist identisch mit der Compilierungszeit. D.h. für dich das du nur durch die Resourcen des Modules iterieren musst bis du die erste findest. Aus dieser Resource liest du dann das Datum aus.

Gruß Hagen

Luckie 11. Nov 2003 16:28

Re: Compilierdatum
 
Code von Nico:
Delphi-Quellcode:
function GetImageLinkTimeStamp(const FileName: string): DWORD;
const
  INVALID_SET_FILE_POINTER = DWORD(-1);
  BorlandMagicTimeStamp = $2A425E19; // Delphi 4-6 (and above?)
  FileTime1970: TFileTime = (dwLowDateTime:$D53E8000; dwHighDateTime:$019DB1DE);
type
  PImageSectionHeaders = ^TImageSectionHeaders;
  TImageSectionHeaders = array [Word] of TImageSectionHeader;
type
  PImageResourceDirectory = ^TImageResourceDirectory;
  TImageResourceDirectory = packed record
    Characteristics: DWORD;
    TimeDateStamp: DWORD;
    MajorVersion: Word;
    MinorVersion: Word;
    NumberOfNamedEntries: Word;
    NumberOfIdEntries: Word;
  end;
var
  FileHandle: THandle;
  BytesRead: DWORD;
  ImageDosHeader: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
  SectionHeaders: PImageSectionHeaders;
  Section: Word;
  ResDirRVA: DWORD;
  ResDirSize: DWORD;
  ResDirRaw: DWORD;
  ResDirTable: TImageResourceDirectory;
  FileTime: TFileTime;
begin
  Result := 0;
  // Open file for read access
  FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, 0, 0);
  if (FileHandle <> INVALID_HANDLE_VALUE) then
  try
    // Read MS-DOS header to get the offset of the PE32 header
    // (not required on WinNT based systems - but mostly available)
    if not ReadFile(FileHandle, ImageDosHeader, SizeOf(TImageDosHeader),
      BytesRead, nil) or (BytesRead <> SizeOf(TImageDosHeader)) or
      (ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) then
    begin
      ImageDosHeader._lfanew := 0;
    end;
    // Read PE32 header (including optional header
    if (SetFilePointer(FileHandle, ImageDosHeader._lfanew, nil, FILE_BEGIN) =
      INVALID_SET_FILE_POINTER) then
    begin
      Exit;
    end;
    if not(ReadFile(FileHandle, ImageNtHeaders, SizeOf(TImageNtHeaders),
      BytesRead, nil) and (BytesRead = SizeOf(TImageNtHeaders))) then
    begin
      Exit;
    end;
    // Validate PE32 image header
    if (ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE) then
    begin
      Exit;
    end;
    // Seconds since 1970 (UTC)
    Result := ImageNtHeaders.FileHeader.TimeDateStamp;

    // Check for Borland's magic value for the link time stamp
    // (we take the time stamp from the resource directory table)
    if (ImageNtHeaders.FileHeader.TimeDateStamp = BorlandMagicTimeStamp) then
    with ImageNtHeaders, FileHeader, OptionalHeader do
    begin
      // Validate Optional header
      if (SizeOfOptionalHeader < IMAGE_SIZEOF_NT_OPTIONAL_HEADER) or
        (Magic <> IMAGE_NT_OPTIONAL_HDR_MAGIC) then
      begin
        Exit;
      end;
      // Read section headers
      SectionHeaders :=
        GetMemory(NumberOfSections * SizeOf(TImageSectionHeader));
      if Assigned(SectionHeaders) then
      try
        if (SetFilePointer(FileHandle,
          SizeOfOptionalHeader - IMAGE_SIZEOF_NT_OPTIONAL_HEADER, nil,
          FILE_CURRENT) = INVALID_SET_FILE_POINTER) then
        begin
          Exit;
        end;
        if not(ReadFile(FileHandle, SectionHeaders^, NumberOfSections *
          SizeOf(TImageSectionHeader), BytesRead, nil) and (BytesRead =
          NumberOfSections * SizeOf(TImageSectionHeader))) then
        begin
          Exit;
        end;
        // Get RVA and size of the resource directory
        with DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] do
        begin
          ResDirRVA := VirtualAddress;
          ResDirSize := Size;
        end;
        // Search for section which contains the resource directory
        ResDirRaw := 0;
        for Section := 0 to NumberOfSections - 1 do
        with SectionHeaders[Section] do
          if (VirtualAddress <= ResDirRVA) and
            (VirtualAddress + SizeOfRawData >= ResDirRVA + ResDirSize) then
          begin
            ResDirRaw := PointerToRawData - (VirtualAddress - ResDirRVA);
            Break;
          end;
        // Resource directory table found?
        if (ResDirRaw = 0) then
        begin
          Exit;
        end;
        // Read resource directory table
        if (SetFilePointer(FileHandle, ResDirRaw, nil, FILE_BEGIN) =
          INVALID_SET_FILE_POINTER) then
        begin
          Exit;
        end;
        if not(ReadFile(FileHandle, ResDirTable,
          SizeOf(TImageResourceDirectory), BytesRead, nil) and
          (BytesRead = SizeOf(TImageResourceDirectory))) then
        begin
          Exit;
        end;
        // Convert from DosDateTime to SecondsSince1970
        if DosDateTimeToFileTime(HiWord(ResDirTable.TimeDateStamp),
          LoWord(ResDirTable.TimeDateStamp), FileTime) then
        begin
          // FIXME: Borland's linker uses the local system time
          // of the user who linked the executable image file.
          // (is that information anywhere?)
          Result := (ULARGE_INTEGER(FileTime).QuadPart -
            ULARGE_INTEGER(FileTime1970).QuadPart) div 10000000;
        end;
      finally
        FreeMemory(SectionHeaders);
      end;
    end;
  finally
    CloseHandle(FileHandle);
  end;
end;
Rückgabewert ist ein Unix TimeStamp.

APP 11. Nov 2003 18:06

Re: Compilierdatum
 
Hallo Luckie,
bitte in die CodeLib stellen!

p.s.
Das ist ja ein richtiger Schatz :thuimb:

Delphianer 11. Nov 2003 18:37

Re: Compilierdatum
 
Hallo Luckie und negaH,

das klingt beides gut. Ich werde es ausprobieren, danke!

Viele Grüße!

DRPEnc 14. Mär 2004 11:20

Re: Compilierdatum
 
Delphi-Quellcode:
Label1.Caption:= DateTimeToStr(UnixToDateTime(GetImageLinkTimeStamp(Application.ExeName)));
Hab ich ausprobiert. Bekomme aber diese Fehlermeldung:

"Undeclared Identifier UnixToDateTime"

Was mach ich falsch, oder was hab ich vergessen?

Würde gerne Datum und Zeit in die Caption der Form1 einbringen. So wie im Programm VirtualDub...

Ich denke ich hab ne variable vergessen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz