Unify standard and Windows version

Started by obetz, June 21, 2019, 11:28:07 AM

Previous topic - Next topic

obetz

Hi Phil,

did you ever consider to consolidate the standard version and the Windows version of ExifTool in one file?

The differences are small:

1. The link following code. I didn't try whether this hurts with Windows, but it could simply be skipped if Windows is detected.

2. The "filename embedded arguments" likely won't hurt in the standard version. BTW: Using my Perl launcher, the parameters need to be extracted from $^X instead of $0.

3. The help. Instead of modifying the whole exiftool script and extracting parts of it at runtime to a text file in %temp%, you could create such a help text file offline and bundle it with the ExifTool distribution. Then it would be easy to select the output method at runtime (perldoc or "more").

Oliver

Phil Harvey

Hi Oliver,

This is a good idea.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

obetz

searching $^X instead of (or in addition to) $0 for "parameters in brackets" would save me from patching ExifTool when I prepare the installer.

I can't decide about the cleaner method:

  • Simply search both $^X and $0 for parameters in brackets. Seems to be foolproof.
  • Check the environment and decide whether to use $^X or $0.

In the mean, I also tried this: The "link following" check if (-l $0) {... doesn't need to be removed in the Windows version, since a "-l" test is always false in current Windows Perl and even my $lnk = eval { readlink $ARGV[0] }; wouldn't harm.

Oliver

obetz

Quote from: Phil Harvey on June 21, 2019, 11:36:33 AM
This is a good idea.

May I bump this topic?

At least points 1. "link following code" and 2. "filename arguments" seem to be pretty easy - see my posting dated 2019-07-05.

Maybe you also want to add (parts of) the "even more verbose" -ver output described in https://exiftool.org/forum/index.php/topic,10223.msg53445.html

Oliver

herb

Hello Phil, hello Oliver,

@Oliver: I tried to follow all your investigations to replace the Windows version of Exiftool.exe with your Ppl.exe=Exiftool.exe.
As far as I see this could be a good solution, but I have the following question:

(Windows)Exiftool.exe is also used by other applications (e.g. XnViewMP or IMatch) and the *.exe file is stored in a subdirectory of the application installation directory.
For me an advantage is that all these Exiftool.exe files use the "unpacked Perl modules" in ONE common directory - in %appdata%\... or defined by global environment variable PAR_GLOBAL_TEMP.

At the moment I do not see how this can be achieved using your Ppl(exiftool).exe.
All necessary files stored in directory "exiftool_files" should be stored only once on a Windows system.

Best regards
Herb

obetz

Herb, since this thread is about the merge of the exiftool and windows_exiftool scripts, I answer your posting in https://exiftool.org/forum/index.php/topic,10128.msg54593.html#msg54593

Phil Harvey

Hi Oliver,

Sorry for being so slow on this.  I'm looking into the $0/$^X business now...

I don't really like the idea of patching windows_exiftool to check both $0 and $^X for arguments in brackets, but I suppose it would be OK to do this.  However, I don't want to patch ExifTool.pm to check both directories for the config file since this would conflict with the documented behaviour.

If I could somehow check the environment to determine with certainty that your exe version is running, then I could patch both files to add an "if" statement and use $^X in this case.  Do you have any ideas about how this could be done?  Would it be possible for your launcher to set a special environment variable that ExifTool could check?

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

obetz

Quote from: Phil Harvey on March 04, 2020, 08:52:49 AM
I don't really like the idea of patching windows_exiftool to check both $0 and $^X for arguments in brackets, but I suppose it would be OK to do this. 

However, I don't want to patch ExifTool.pm to check both directories for the config file since this would conflict with the documented behaviour.
I agree.

Quote from: Phil Harvey on March 04, 2020, 08:52:49 AM
If I could somehow check the environment to determine with certainty that your exe version is running, then I could patch both files to add an "if" statement and use $^X in this case.  Do you have any ideas about how this could be done?  Would it be possible for your launcher to set a special environment variable that ExifTool could check?

I could set an environment variable or a command line parameter but maybe that's not even necessary.

We need to distinguish three (Windows-) environments:

1. PAR packed
$0  : Z:\path_to_exiftool\exiftool-could-be-renamed.exe
$^X: perl.exe (par lies to us, there is no perl.exe)

There are many par specific environment variables, for example PAR_INITIALIZED, PAR_PROGNAME, PAR_SPAWNED so this case is easy to detect.
And par sets some strange, non-existing include directories like "CODE(0x3400d74)"

2. Script called by standard perl.exe
$0  : Z:\path_to_exiftool\exiftool-could-be-renamed.pl
$^X: Y:\path_to_perl\perl5.xx.y.exe

3. Perl launcher
$0  : Z:\path_to_exiftool\exiftool_files\exiftool.pl
$^X: Z:\full_path\ExifTool-could-be-renamed.exe

Currently, "exiftool_files\exiftool.pl" is hard coded in my launcher. Of course, we can change the directory name as well as the script name (think about exiftool4ppl.pl or blkqximukzcdzxnr0fhh.pl)

But even with a unique script name, checking only $0 wouldn't be 100% safe because people could run the script with perl.exe. I ship the original perl.exe in the archive and installer to make this possible.

But checking $^X in combination with $0 should be safe enough: If the directory part from $^X concatenated with the hard coded part of the script path matches $0, we can be rather sure that the launcher is used.

Phil Harvey

This sounds reasonable.  Are the directory delimiters of $0 and $^X always "\"?  Also, what happens if the directory name contains Unicode characters?  And is this impervious to changes in case (ie. file names in upper case but invoked using lower case)?

If all this is OK, the how about something like changing this in ExifTool.pm:

    -r $file or $config =~ /^\// or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config;

to this

    my $dir = $0;
    if ($^O eq 'MSWin32') {
        my $test = $^X;
        $dir = $^X if $test =~ s/\\[^\\]*$/\\exiftool_files\\exiftool.pl/ and $0 eq $test;
    }
    -r $file or $config =~ /^\// or $file = ($dir =~ /(.*[\\\/])/ ? $1 : './') . $config;


And similarly in the exiftool script.

(This isn't the most heart-warming solution because it couldn't be used by other packages)

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

obetz

Quote from: Phil Harvey on March 04, 2020, 12:53:02 PM
[...]
(This isn't the most heart-warming solution because it couldn't be used by other packages)
I agree.

Probably the cleanest method is to add a command line argument.

What do you think about "-xpath" or more cryptic as very first parameter (even before -config!) to indicate that $^X shall be used instead of $0?

How shall we forward this information to ExifTool.pm?

Oliver

obetz

Find a modified launcher attached: It inserts "-xpath" as first parameter. Use it instead of "exiftool.exe" from my package.

I hacked exiftool to make use of it, but I'm no Perl monk - you likely find a cleaner solution:

exiftool near line 17:

my $exePath;
BEGIN {
    if (@ARGV and $ARGV[0] eq '-xpath') {
        shift;
        $exePath = $^X;
    }
    else{
        $exePath = $0;
    }
    $Image::ExifTool::exePath = $exePath;

    # get exe directory
    $exeDir = ($exePath =~ /(.*)[\\\/]/) ? $1 : '.';


exiftool near line 345

# add arguments embedded in filename (Windows .exe version only)
if ($exePath =~ /\(([^\\\/]+)\)(.exe|.pl)?$/i) {


and in exiftool.pm around line

    $Image::ExifTool::exePath = $0 if (not defined $Image::ExifTool::exePath);
    -r $file or $config =~ /^\// or $file = ($Image::ExifTool::exePath =~ /(.*[\\\/])/ ? $1 : './') . $config;


This way, $^X is only used if ExifTool is invoked by my Perl launcher.

Oliver

Phil Harvey

I like this idea better.  I'll implement this in ExifTool 11.91.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

obetz

o.k., change the parameter name if you like.

Phil Harvey

-xpath is good.  I'll add this as an undocumented feature for now.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

obetz

I wasn't able to verify it, but as far as I see, exiftool_windows line 338 needs to use exePath instead of $0

I'll try to check this tomorrow.

BTW: Is it really intended that "$exeDir/lib" is added to the lib search path in the par version? I can't imagine that a Windows user adds a lib dir beneath exiftool.exe and puts some Perl libraries there to be used by ExifTool.

Oliver