如何检测编译exe的Delphi编译器版本?

时间:2011-12-03 14:49:18

标签: delphi compiler-construction version

如何检测使用哪个版本的Delphi编译预先存在的.exe文件?我不一定需要用代码来做这件事。

我尝试过PEiD但它无法检测版本是否比Delphi 7更新。

3 个答案:

答案 0 :(得分:13)

下载IDR (Interactive Delphi Reconstructor)的各种文件,将其解压缩到一个文件夹并运行它。将已编译的可执行文件加载到IDR中,它会告诉您编译可执行文件的版本(对我来说已经证明是准确的)。

答案 1 :(得分:9)

替代解决方案:

XN Resource Editor中打开已编译的可执行文件。在树中的“ RC数据”下,您会找到 DVCLAL 。展开它并选择“语言中立”。现在,您将看到一个无意义的字符串,其中包含同等无意义的HEX等效字符。

此HEX实际上标识了构建可执行文件的编译器版本。你可以使用Delphi这个单词谷歌这个HEX,你应该能够很快地确定HEX来自哪个编译器。

享受!

答案 2 :(得分:6)

您可以使用此来源为您提供程序集信息。在主程序集中,您可以看到名称和版本,它将为您提供编译器的名称和版本。它是一个控制台应用程序,其中 param 1 exe 文件。

可在此处查看版本:

  

http://wiki.delphi-jedi.org/wiki/JEDI_Help:CompilerVersions

查看它与vbuild的版本;即,

12.xxxx - Delphi 2009 和15.xxxx - Delphi XE

但是,这仅适用于 XE 。使用 XE2 ,exe中的内容已经发生了变化。

 program versionchk;

    {$APPTYPE CONSOLE}

    uses
      ActiveX,
      Classes,
      Windows,
      Variants,
      ComObj,
      StrUtils,
      SysUtils;

    type
      TAssemblyIdentity=record
        &type : string;
        name    : string;
        language: string;
        processorArchitecture   : string;
        version : string;
        publicKeyToken: string;
      end;

      TRequestedExecutionLevel=record
        level    : string;
        uiAccess : string;
      end;

      TManifiestReader=class
      private
        FFileName: string;
        FManifest: AnsiString;
        FMainAssemblyIdentity: TAssemblyIdentity;
        FHasManifest: Boolean;
        FDependentAssembly: TAssemblyIdentity;
        FManifestVersion: string;
        FRequestedExecutionLevel: TRequestedExecutionLevel;
        procedure GetManifest;
        procedure LoadManifestData;
        function  VarNullToStr(Value:OleVariant):string;
      public
        property FileName : string read FFileName;
        property Manifest : AnsiString read FManifest;
        property ManifestVersion : string read FManifestVersion;
        property MainAssemblyIdentity : TAssemblyIdentity read FMainAssemblyIdentity;
        property DependentAssembly : TAssemblyIdentity read FDependentAssembly;
        property HasManifest : Boolean read FHasManifest;
        property RequestedExecutionLevel : TRequestedExecutionLevel read FRequestedExecutionLevel;
        constructor Create(const AFileName:string);
      end;

    { TReadManifiest }

    constructor TManifiestReader.Create(const AFileName: string);
    begin
      FFileName:=AFileName;
      FHasManifest:=False;
      GetManifest;
      LoadManifestData;
    end;

    procedure TManifiestReader.GetManifest;
    var
      hModule  : THandle;
      Resource : TResourceStream;
    begin
      FManifest:='';
      hModule:=LoadLibraryEx(PChar(FileName),0,LOAD_LIBRARY_AS_DATAFILE);
      try
         if hModule=0 then RaiseLastOSError;
         if FindResource(hModule, MakeIntResource(1), RT_MANIFEST)<>0 then
         begin
           Resource:=TResourceStream.CreateFromID(hModule,1,RT_MANIFEST);
           try
             SetString(FManifest, PAnsiChar(Resource.Memory),Resource.Size);
             FHasManifest:=True;
           finally
             Resource.Free;
           end;
         end;
      finally
          FreeLibrary(hModule);
      end;
    end;

    procedure TManifiestReader.LoadManifestData;
    const
     assembly_namespace_V1='urn:schemas-microsoft-com:asm.v1';
     assembly_namespace_V2='urn:schemas-microsoft-com:asm.v2';
     assembly_namespace_V3='urn:schemas-microsoft-com:asm.v3';
    var
      XmlDoc : OleVariant;
      ns     : string;
      Node   : OleVariant;
    begin
      if Trim(FManifest)='' then exit;
      XmlDoc       := CreateOleObject('Msxml2.DOMDocument.6.0');
      XmlDoc.Async := False;
      try
        XmlDoc.LoadXML(FManifest);
        XmlDoc.SetProperty('SelectionLanguage','XPath');

        if (XmlDoc.parseError.errorCode <> 0) then
         raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);

        //set the namespaces alias
        ns := Format('xmlns:a=%s xmlns:b=%s xmlns:c=%s',[QuotedStr(assembly_namespace_V1),QuotedStr(assembly_namespace_V2),QuotedStr(assembly_namespace_V3)]);
        XmlDoc.setProperty('SelectionNamespaces', ns);

        //get the version of the manifest
        Node:=XmlDoc.selectSingleNode('/a:assembly/@manifestVersion');
        if not VarIsNull(Node) and not VarIsClear(Node) then
        FManifestVersion:=Node.text;

        Node:=XmlDoc.selectSingleNode('/a:assembly/a:assemblyIdentity');
        if not VarIsNull(Node) and not VarIsClear(Node) then
        begin
          FMainAssemblyIdentity.&type   :=Node.getAttribute('type');
          FMainAssemblyIdentity.name    :=Node.getAttribute('name');
          FMainAssemblyIdentity.language:=VarNullToStr(Node.getAttribute('language'));
          FMainAssemblyIdentity.version :=Node.getAttribute('version');
          FMainAssemblyIdentity.processorArchitecture:=VarNullToStr(Node.getAttribute('processorArchitecture'));
          FMainAssemblyIdentity.publicKeyToken       :=VarNullToStr(Node.getAttribute('publicKeyToken'));
        end;

        Node:=XmlDoc.selectSingleNode('/a:assembly/a:dependency/a:dependentAssembly/a:assemblyIdentity');
        if not VarIsNull(Node) and not VarIsClear(Node) then
        begin
          FDependentAssembly.&type   :=Node.getAttribute('type');
          FDependentAssembly.name    :=Node.getAttribute('name');
          FDependentAssembly.language:=VarNullToStr(Node.getAttribute('language'));
          FDependentAssembly.version :=Node.getAttribute('version');
          FDependentAssembly.processorArchitecture:=VarNullToStr(Node.getAttribute('processorArchitecture'));
          FDependentAssembly.publicKeyToken       :=VarNullToStr(Node.getAttribute('publicKeyToken'));
        end;

        Node:=XmlDoc.selectSingleNode('/a:assembly/b:trustInfo/b:security/b:requestedPrivileges/b:requestedExecutionLevel');
        if VarIsNull(Node) or VarIsClear(Node) then
          Node:=XmlDoc.selectSingleNode('/a:assembly/c:trustInfo/c:security/c:requestedPrivileges/c:requestedExecutionLevel');
        if not VarIsNull(Node) and not VarIsClear(Node) then
        begin
          FRequestedExecutionLevel.level   :=Node.getAttribute('level');
          FRequestedExecutionLevel.uiAccess:=VarNullToStr(Node.getAttribute('uiAccess'));
        end;

      finally
        XmlDoc:=Unassigned;
      end;
    end;

    function TManifiestReader.VarNullToStr(Value: OleVariant): string;
    begin
      if VarIsNull(Value) then
        Result:=''
      else
        Result:=VarToStr(Value);
    end;

    Var
      ManifestReader : TManifiestReader;
    begin
     try
        CoInitialize(nil);
        try
          ManifestReader:=TManifiestReader.Create(ParamStr(1));
          try
            //Writeln(ManifestReader.Manifest);

            Writeln('Manifest version '+ManifestReader.ManifestVersion);
            Writeln('Main Assembly Identity');
            Writeln('----------------------');
            Writeln('type     '+ManifestReader.MainAssemblyIdentity.&type);
            Writeln('name     '+ManifestReader.MainAssemblyIdentity.name);
            Writeln('language '+ManifestReader.MainAssemblyIdentity.language);
            Writeln('version  '+ManifestReader.MainAssemblyIdentity.version);
            Writeln('processorArchitecture '+ManifestReader.MainAssemblyIdentity.processorArchitecture);
            Writeln('publicKeyToken        '+ManifestReader.MainAssemblyIdentity.publicKeyToken);
            Writeln('');

            Writeln('Dependent Assembly Identity');
            Writeln('---------------------------');
            Writeln('type     '+ManifestReader.DependentAssembly.&type);
            Writeln('name     '+ManifestReader.DependentAssembly.name);
            Writeln('language '+ManifestReader.DependentAssembly.language);
            Writeln('version  '+ManifestReader.DependentAssembly.version);
            Writeln('processorArchitecture '+ManifestReader.DependentAssembly.processorArchitecture);
            Writeln('publicKeyToken        '+ManifestReader.DependentAssembly.publicKeyToken);
            Writeln('');

            Writeln('Requested Execution Level');
            Writeln('---------------------------');
            Writeln('level     '+ManifestReader.RequestedExecutionLevel.level);
            Writeln('uiAccess  '+ManifestReader.RequestedExecutionLevel.uiAccess);

          finally
            ManifestReader.Free;
          end;
        finally
          CoUninitialize;
        end;
     except
        on E:Exception do
            Writeln(E.Classname, ':', E.Message);
     end;
      Readln;
    end.