ReNamer:Scripts:TrID

From den4b Wiki
Jump to: navigation, search

This script integrates the famous TrID library which is used for detecting file extensions. Discussions about this script and some script variants can be found in the following forum threads: ReNamer and TrID library for detecting file extension and ReNamer: MSI files are detected as PPT/XLS/DOC files.

Note: At the moment these scripts work only on ANSI filenames (non-Unicode). This is a limitation of the library, which may be addressed in later versions.

Requirements

Code: Basic

Author: Denis Kozlov. Date: 16 Dec 2008. Initial version. Sets the file extension to the top matching extension. Can be easily extended.

  • Tested with ReNamer Beta from 5 Dec 2008
{ TrID Script }

// TrID DLL exported functions
function TridAnalyze: integer;
  external 'TrID_Analyze@TrIDLib.dll stdcall';
function TridSubmitFileA(szFileName: pchar): integer;
  external 'TrID_SubmitFileA@tridlib.dll stdcall';
function TridLoadDefsPack(szPath: pchar): integer;
  external 'TrID_LoadDefsPack@tridlib.dll stdcall';
function TridGetInfo(lInfoType: integer; lInfoIdx: integer; sBuf: pchar): integer;
  external 'TrID_GetInfo@tridlib.dll stdcall';

// Constants for TrID_GetInfo
const
  TRID_GET_RES_NUM         = 1;    // Get the number of results available
  TRID_GET_RES_FILETYPE    = 2;    // Filetype descriptions
  TRID_GET_RES_FILEEXT     = 3;    // Filetype extension
  TRID_GET_RES_POINTS      = 4;    // Matching points
  TRID_GET_VER             = 1001; // TrIDLib version (major * 100 + minor)
  TRID_GET_DEFSNUM         = 1004; // Number of filetypes definitions loaded

function GetTopExtensions(Max: Integer): String;
var
  S: String;
  Num, I: Integer;
begin
  Result := '';
  SetLength(S, 100);
  Num := TridGetInfo(TRID_GET_RES_NUM, 0, PChar(S));
  if Num > 0 then
  begin
    if Num > Max then
      Num := Max;
    for I:=1 to Num do
      begin
        TridGetInfo(TRID_GET_RES_FILEEXT, I, PChar(S));
        if I > 1 then Result := Result + '|';       
        Result := Result + String(PChar(S));
      end;
  end;
end;

var
  Initialized: Boolean;

begin
  if not Initialized then
  begin
    TridLoadDefsPack('');
    Initialized := True;
  end;
  TridSubmitFileA(PChar(FilePath));
  if TridAnalyze <> 0 then
    FileName := WideStripExtension(FileName)+'.'+GetTopExtensions(1);
end.

Code: Advanced

Author: Andrew. Date: 27 Nov 2011. An extended version by Andrew. Read comments in the script for more information.

  • Requires ReNamer 5.60+ Beta 10 or later
{ TrID Script v6 }

// v1 - Original script by Denis
// v2 - Modified by Andrew to output lowercase extensions and detect presence of TrIDLib.dll and TrIDDefs.trd
// v3 - Modified by Andrew to keep existing extensions if not identified properly
// v4 - Modified by Andrew to display multiple possible extensions
// v5 - Modified by Andrew to display multiple possible extensions with cutoff of 20%
// v6 - Modified by Andrew to fix a path-related issue

// Important: Download http://mark0.net/download/tridlib-free.zip and http://mark0.net/download/triddefs.zip,
// then extract TrIDLib.dll and TrIDDefs.trd to ReNamer.exe's folder/directory or else the script will fail

// TrID DLL exported functions
function TridLoadDefsPack(szPath: PChar): Integer;
  external 'TrID_LoadDefsPack@TrIDLib.dll stdcall';
function TridSubmitFileA(szFileName: PChar): Integer;
  external 'TrID_SubmitFileA@TrIDLib.dll stdcall';
function TridAnalyze: Integer;
  external 'TrID_Analyze@TrIDLib.dll stdcall';
function TridGetInfo(lInfoType: Integer; lInfoIdx: Integer; sBuf: PChar): Integer;
  external 'TrID_GetInfo@TrIDLib.dll stdcall';

// Constants for TrID_GetInfo etc.
const
  TRID_GET_RES_NUM     = 1;  // Get the number of results
  TRID_GET_RES_FILEEXT = 3;  // Filetype extension
  TRID_GET_RES_POINTS  = 4;  // Matching points
  TRID_GET_RES_CUTOFF  = 20; // Cutoff percentage for results

function GetExtensions(): WideString;
var
  Str1, Str2: String;
  I, NumRes, NumPts, TotPts: Integer;

begin
  Result := '';
  SetLength(Str1, 100);
  NumRes := TridGetInfo(TRID_GET_RES_NUM, 0, PChar(Str1));
  if (NumRes > 0) then
  begin
    for I := 1 to NumRes do
      TotPts := TotPts + TridGetInfo(TRID_GET_RES_POINTS, I, PChar(Str1));
    for I := 1 to NumRes do
    begin
      NumPts := TridGetInfo(TRID_GET_RES_POINTS, I, PChar(Str1));
      if ((NumPts*100/TotPts) > TRID_GET_RES_CUTOFF) then
      begin
        TridGetInfo(TRID_GET_RES_FILEEXT, I, PChar(Str1));
        Str2 := LowerCase(String(PChar(Str1)));
        if (Length(Str2)>0) And (Pos(Str2, Result)=0) then
        begin
          if (I > 1) then Result := Result + '/';
          Result := Result + Str2;
        end;
      end;
    end;
  end;
end;

var
  Initialized: Boolean;
  AppPath, FileExts: WideString;

begin
  if (not Initialized) then
  begin
    Initialized := True;
    AppPath := WideExtractFilePath(GetApplicationPath());
    if (TridLoadDefsPack(AppPath) = 0) then
    begin
      WideDeleteFile(AppPath + 'TrIDDefs.trd');
      if (DialogYesNo('Error! TrIDDefs.trd not found in the program directory (' + AppPath + ')!'
      + #13#10#13#10 + 'Do you want to download the latest version from the TrID website now?')) then
        ShellOpenFile('http://mark0.net/soft-trid-e.html');
      Exit;
    end;
  end;
  if (TridSubmitFileA(PChar(FilePath)) <> 0) then
  begin
    if (TridAnalyze <> 0) then
    begin
      FileExts := GetExtensions();
      if (Length(FileExts) > 0) then
        FileName := WideStripExtension(FileName) + '.' + FileExts;
    end;
  end;
end.