Substitute exiftool.exe w/ perl version on Windows?

Started by Marsu42, September 15, 2011, 06:26:25 PM

Previous topic - Next topic

Phil Harvey

Wow, that definitely is very sneaky.  You could simplify the code a bit:


    int i = 1;
    /* scrap the first two args if intercepted by registry debugger */
    if (argc > 2 && !strcmp(argv[1],"-skip2args")) {
        i += 2;
    }

    /* copy over the remaining exiftool arguments */
    for (; i<argc; ++i) {
        args[argc2++] = argv[i];
    }
    args[argc2] = NULL;     /* NULL to end argument list */


This also has the advantage of not modifying the input argv array, which I never like to do.

- 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 ($).

bs27975

#16
My usage / some suggestions.

(My) Environment Notes:
- Win xp & 7
- perl happy
- I have a mapped drive, E:, where I put everything I download. Static files. e.g. Downloads, software, .zip's, .pdf's, etc. For example, my Canon sw downloads as well as the manuals are all in E:\Canon. Everything in the house maps E:. Thus, I have E:\ExifTool. (Which has the gui in there, too.)

I have come across this thread because I'm got tired of seeing PAR-USER directories everywhere. And in playing around I was re-reminded that running the perl version directly is MUCH faster. (And no par-user files.) But, of course, exiftoolgui fails for lack of .exe. [To be sure, better PAR-USER directory than no exiftool! But thought there might be a 'better way'(tm), there is {somewhat}, and thought I would share.]

Suggestion 1: Documentation Page
- You might note that setting PAR_GLOBAL_TEMP will stop the par-USER directories from propagating everywhere. e.g. My %windir%\exiftool.cmd file might be:
SET PAR_GLOBAL_TEMP=%TEMP%\par-cache
E:\Exiftool\Exiftool.exe %*
- of course, setting the environment variable globally, and having exiftool.exe in the path negates the need for this script. Even without, after the first invocation, the cache is present, and exiftool speeds up dramatically.
[The forum thread pointing out where par is led me to this.]

Suggestions 2: exiftool_stub -
- Could -h be modified to simply print out the usage as it currently does (with no envvars set), and append something like 'Currently set to:' (and continue with what -h already does).
[Having set EXIFTOOL, and it not working, I then typed just exiftool -h to see where I was supposed to have put it, only to be told where I had set it, and no way to know where it default expected it to be. Once I discovered and fixed my typing mistake, all was well, but getting there ...]
- Could no arguments, '-h', '--help', and '/?' all print the usage. [All are standards for provoking usage.]
- There is one usage this does not cover, calling the stub with no arguments produces:
Can't open perl script "c:\perl\site\bin\exiftool": No such file or directory
Error executing perl
- this makes sense, for the stub, but is probably not what you desire. What you probably want is what happens when exiftool.exe (non-stub) or 'perl exiftool' is run without arguments - exiftool usage.
- Perhaps (stub) 'exiftool -usage' could do what it does (the stub), then try to invoke exiftool proper without arguments. Interestingly 'exiftool -ver' and 'exiftool -list' do the expected. It's only the case of no arguments where the usual does not happen. (Because it's the stub.) Or, create '-usage' as an exiftool option? [Hard call to make, 'cause /?, -h, --help, <no args> all still apply, stub, and non. Perhaps accomodating the special case, (stub) 'exiftool -usage' -> (perl) 'perl exiftool' (only) makes some sense.]
- Could EXIFTOOL be the directory containing the exiftool file, not the exiftool file itself? (Or create EXIFTOOLDIR?)
- Could the stub exe check for the existence of exiftool before trying to call it? Instead of returning:
Can't open perl script "c:\perl\site\bin\exiftool": No such file or directory
Error executing perl
(Return the usage, of the stub, at least.)
- Interestingly, SET EXIFTOOL=".\exiftool", works. (Allowing <mypath>\<exiftoolstub>.exe' to be called from anywhere, any computer, and it just works. But the environment variable still must be set. (Trusting each computer's path to contain the path to the perl executable.)
- If the location specified in EXIFTOOL, or if EXIFTOOL is not defined, could it check for the existence in the current directory?
- this gets around the need for any environment variable at all (and therefore, a maintenance task not needed for each computer). [Assuming perl is on the local path.]
- I suppose you would check for exiftool.pl before just exiftool.
- Arguably, I suppose, you could walk the path string, but that may be more work than you want to do. I would find it useful if you checked for 'exiftool.pl', then 'exiftool', [then exiftool.exe, I suppose?], in the given EXIFTOOL dir, then the current dir. (Oops, watch for calling yourself, I suppose.)
- Gotcha here: I am assuming, above, the current dir path to check is "%0\..", not the current working directory. (My static .exe's are in E:, but my data is in I: - so calls of E:\Exiftool\Exiftool mypic.jpg are normal, being in I:\me at the time. [Windows programs are installed as normal, not to E:.])

Why have I done all this? Having gotten the par-USER directory down to a single instance, then none by calling 'perl exiftool', exiftoolgui is still unhappy without a .exe. Thus my happiness at finding the stub - and entering these notes as I went through the process of implementing it into my workflow.

Sadly, exiftoolgui is entirely unhappy at the moment, with frequent list out of bounds messages. Something I'll have to pursue, separately.


Suggestions based on help threads I've seen elsewhere in the forum. When having difficulties:
- from a command line, do 'perl exiftool' (or 'perl .\exiftool') wherever you have put exiftool. If that's unhappy (e.g. no perl executable in path), make that happy, first. For those cases where people aren't able to get a perl version going. i.e. Phil can't solve your perl execution problems, only problems once some perl has opened his program.
- from a command line, call the full executable file name of the file, make sure something else in your path isn't schmucking you. e.g. C:\Windows\ExifTool.Cmd (which might call C:\Windows\ExifTool.Exe, or perl C:\Windows\ExifTool. Note, the final dot might be necessary, there. (e.g. There are times when 'notepad readme' fails, but 'notepad readme.' works. Particularly noticeable on %windir%\System32\drivers\etc\hosts.) Using full paths can be handy when exiftool.bat, exiftool.cmd, and exiftool.exe all exist in the same directory.
- note that a .exe is called before a .cmd (or a .bat). So you will be unhappy if a directory contains exiftool.exe and exiftool.cmd, .cmd surrounding the .exe call with stuff like environment variable setting. Rename exiftool.exe to exiftoolexe.exe and change the .cmd appropriately, to get happy. But then you've just lost the ability to drop in new versions of exiftool.exe when they arrive.

Hopefully useful notes.

Also - links in the forum to other places don't appear to work if anonymous (reading) / not logged in. I was baffled by the link to this thread not going anywhere useful (forum top). I just happened to try registering and logging in - then things started working. (Perhaps this is a forum configuration issue? The casual reader clicking on a forum link, I would have thought, would correctly go to the linked article.)

Thank you all for being here!

bs27975

Quote from: Marsu42 on September 16, 2011, 01:30:52 PM
Quote from: Phil Harvey on September 16, 2011, 09:33:03 AM
On unix, execv() will replace the current process image with another.
But on window-mingw, it will create another process and terminate current
one[

Indeed it's a mingw issue: I compiled it with the Cygwin POSIX emulation layer and it works. Of course, the Cygwin dll has to be distributed along with the exe, and it cannot be x64 code (thus loading the Win32 emulation layer on a 64-bit OS which is regrettable when using 64bit Lightroom with 64bit Perl). However, the usual Cygwin performance hit shouldn't count here.

Concerning the environment issue: As I said, I have forgotten just about everything about C, but even if the app sets its own environment, there should be a way to still access the global system environment? Edit: I just read that you'll try this approach, I'll try it tomorrow.

May I point out, the stub's README.txt indicates Makefile is included, but I don't see it. With apologies for laziness, could I ask that it be included?

I programmed C (extensively) for some years, but not for some years. And I've been using Cygwin for, like, forever. But never compiled anything. Thus, a makefile would jump start me somewhat. (P&TY).

In my case, at the moment, exiftoolgui is unhappy (I presume, but don't know) with the stub, and compiling my own would let me put in some debugs. [Something that used to be happy non-stub is now unhappy with stub. I suspect redirection, paths, or current directory is the problem, but am having a hard time figuring it out.]

Phil Harvey

I'll read through your long post when I have more time.

For now I'll just say that the "exiftool_stub.zip" in my last post contains the Makefile.

- 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 ($).

photogeek

Fantastic stub tool, Phil!  Thank you!  It works great on my machine with Win7 64 bit and Perl installed in C:\tools\Perl64.  I had to add the global environment variable and viola! the stub started working with no issues whatsoever! 

What the stub did for me is to allow running GeoSetter without the admin permissions. 

Just a thought, since a valid login required for this forum to download the stub, maybe  it can be added to the main download site so that people can get it without having forum membership?  It is a great resource!

Phil Harvey

Thanks.  I'm glad it was useful.  It may help others if you could post more details about your environment settings (ie. where did you change it, and exactly what did you set?)

I had already tried to make attachments downloadable for forum guests (ie. non-members), but couldn't find the setting.

But I googled the smf forum and figured it out.  Non-members can now download forum attachments.

- 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 ($).

photogeek

Q: Why to use exiftool stub?
-------------------------------------------
A: Several programs  that use ExifTool rely on standalone executable (i.e. not the Perl script) to be placed in the specific location.  Having a stub instead of an executable allows having a single Perl version to be used for all the programs. If you run a 64bit version of Windows, there's a performance improvement of running a 64 bit Perl version of ExifTool instead of a compiled executable.  Some programs that rely on the presence of ExifTool executable (as GeoSetter does) may fail to update the images unless the program starts with administrative privileges.  Having a stub instead of an executable allows running the program as a normal user.


Installation steps for Perl, ExifTool, and the stub (using Microsoft Windows 64 bit):
-------------------------------------------
A: The steps below show how to get the Perl version of ExifTool installed on the system into a custom location:


1.   Install Active Perl from: http://www.activestate.com/activeperl/downloads

The default location for Active Perl installation is C:\Perl64.  The location can be changed, or even the whole folder moved.  You can also copy the C:\Perl64 folder to another computer and have Perl running without running the MSI.  I'm not a fan of installing programs in the root directory, so my Perl installation is C:\tools\Perl64, if you decide to move from the default location, make sure the new path does not have spaces.
If you simply copied the content of the Perl64 directory (instead of running the MSI), you will have to modify the path environment variable.  To do that, click Start, right-click on Computer ,  Select Properties. On the left bar, click on a quick link to Advanced system settings.  A new window opens up, select Advanced tab on top and click on Environment Variables... button.  At the bottom of the section titled System variables, find variable entry "Path" and double click on it.  You may edit the Variable value now.  Typically you would just append a new path to the end of the long string. If you installed Perl in C:\tools\Perl64, append this to the end of the Variable value: ";C:\tools\Perl64\site\bin;C:\tools\Perl64\bin"  Don't forget the semicolon in the front. 
You may also add the following registry entry (save the three lines below in a file with an extension REG and run it):
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\Applications\perl.exe\shell\open\command]
@="\"C:\\tools\\Perl64\\bin\\perl.exe\" \"%1\" %*"


2.   Download and unpack ExifTool. 

The file you are interested in downloading is named "Image-ExifTool-X.XX.tar.gz".  Unpack the content of gz and tar in to a local directory.  An open source 7-Zip archiver works well for that.  After unpacking, you should have a folder named Image-ExifTool-X.XX somewhere on your drive.


3.   Get nmake.exe

See if you have nmake.exe (any old version of it should work).  I could not find the old versions on microsoft.com site any more, but the NMAKE is included in the Windows SDK. You can download the full version of Windows SDK and extract the NMAKE from it without installing anything.  The full ISO of the Windows SDK is here: http://www.microsoft.com/en-us/download/details.aspx?id=8442
Once downloaded, 7-Zip can open ISO image just as a regular archive.  Inside the ISO archive, open Setup -> vc_stdamd64 -> vc_stdamd64.cab.  Inside the CAB file, find the FL_nmake_exe_105150_105150_amd64_ln.3643236F.... and extract it somewhere on the hard drive.  Rename the extracted file to nmake.exe and place it in any directory that is listed in the Path environment variable or copy it to the location of the extracted ExifTool source.


4.   Prepare ExifTool package for integration.

Inside of the unpacked Image-ExifTool-X.XX folder, double click on Makefile.pl file.  If you don't have the association set for the pl files, select "open with the program" and pick the location of the Perl command line interpreter (C:\tools\Perl64\bin\perl.exe).  After running Makefile.pl file, it will create a new Makefile file in the same directory.


5.   Install ExifTool

Open administrator command prompt, navigate to abovementioned folder Image-ExifTool-X.XX and run nmake. 
Nmake should finish running showing that multiple files were copied (there should be no error messages).
Run "nmake install" to integrate ExifTool into the Perl environment. 
If everything goes well, there should be no errors at the end of running "nmake install".  On one of the machines, I got "fatal error U1077: perl.exe return code '0xd'".  This happened because one of the Perl environments happened to be pointing to a folder with a space "Program Files", if it ever happens to you, the easiest way to fix it to replace all occurrences of "C:\Program Files \(x86\)\Perl64" with the location where you have Perl installed, as "C:\tools\Perl64".  The file that needs replacing is makefile inside the Image-ExifTool-X.XX folder.  After replacing, rung "nmake install" again.  This should install ExifTool on your machine.


6.   Install ExifTool stub program so that your Perl version of ExifTool runs when the program is called.

Download exiftool_stub.zip from this post and extract the exiftool.exe.  The file should be small, less than 20k in size.  That should tell you that this is the stub and not the full version of ExifTool (as they both have the same name).


7.   Modify the environment variables for ExifTool stub so that the right version of Perl is called.

Open Environment Variables dialog box (see step 1 for directions).  Under the section System variables, click button New... and type in the following values:

Variable name: EXIFTOOL
Variable value: C:\tools\Perl64\site\bin\exiftool

Click OK to close the dialog box and then Apply to apply the new settings.  Close the System Properties window.

The new settings will take the effect only for new windows, so close any command prompt windows you may have still open and reopen them again from the Start menu (rebooting computer also works).  The newly opened windows will be able to see the new settings.   Running the exiftool.exe stub should now execute the Perl version of the tool and run normally.  Copy the stub to any location that needs an executable version of ExifTool.   

Now you should have only one place to maintain the current version of ExifTool and the tool will not require administrative privileges.

Biggest thanks to Phil for the most wonderful tool and for writing the actual stub!


Photogeek

Phil Harvey

Wow, thanks for the detailed step-by-step!  This explains EVERYTHING, and should be a great help for others!

- 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 September 18, 2011, 08:31:54 AM
2012-09-12 - fixed problem with arguments containing spaces

Thanks for this code!

There might be still another problem I wasn't aware of: Quoted parameters can include quotation marks!

boot.c from pp (PAR Packer) has a function shell_quote() dealing with this problem, see  here:
https://github.com/rschupp/PAR-Packer/blob/master/myldr/boot.c

Two more comments on exiftool.c:

  • The "outer n" from line 55 "int n = strlen(argv[0]);" seems to be unused and being hidden by later declarations of "n".
  • "#ifdef __MINGW32__" doesn't seem to reflect the real intention. I guess any "not cygwin" windows compiler needs spawnvp instead of execvp. I didn't investigate a better suited condition, though.

Just my two cents if anybody plans to use or change this code in the future.

I decided not to use spawnvp just to call a trivial program doing just RunPerl(argc+ARGS_ADDED, ourargv, env);.
I will present a different (simpler?) proposal in a new thread.

Oliver

allsan8

I had found photogeek's instructions earlier this year and said to myself, I need to try this.  Today was the day.

Reason for me trying photogeek's instructions:  "Having a stub instead of an executable allows running the program as a normal user."

Unfortunately, I ran into an error.

Before logging into the forum, I see obetz is working on a different install process that has similar benefits.

What I used:

Windows 7 (64-bit)
ActivePerl-5.28
ExifTool 11.52

The error occurred during the nmake install step:

to undefined at C:/ActiveState/Perl64/site/lib/ExtUtils/Install.pm line 141.
NMAKE : fatal error U1077: 'C:\ActiveState\Perl64\bin\perl.exe' : return code '0xff'
Stop.

Line 141:      File::Compare::compare(@_);


I saw in another thread some issues may be due to one's version of Perl.  Not sure if this one.  And I am not sure this is worth tracking down if there will be a similar solution on the horizon.

Thank you.

obetz

Quote from: allsan8 on June 21, 2019, 01:26:33 PM
What I used:

Windows 7 (64-bit)
ActivePerl-5.28
ExifTool 11.52

The error occurred during the nmake install step:

to undefined at C:/ActiveState/Perl64/site/lib/ExtUtils/Install.pm line 141.
NMAKE : fatal error U1077: 'C:\ActiveState\Perl64\bin\perl.exe' : return code '0xff'
Stop.

Line 141:      File::Compare::compare(@_);

What did you make/install, when did you get the error?

Do you use your ActivePerl installation for other things than ExifTool?

Oliver

allsan8

Following photogeek's instructions above ... the error occurred in Step 5:

Quote5.   Install ExifTool

Open administrator command prompt, navigate to abovementioned folder Image-ExifTool-X.XX and run nmake.
Nmake should finish running showing that multiple files were copied (there should be no error messages).
Run "nmake install" to integrate ExifTool into the Perl environment.
If everything goes well, there should be no errors at the end of running "nmake install".  On one of the machines, I got "fatal error U1077: perl.exe return code '0xd'".  This happened because one of the Perl environments happened to be pointing to a folder with a space "Program Files", if it ever happens to you, the easiest way to fix it to replace all occurrences of "C:\Program Files \(x86\)\Perl64" with the location where you have Perl installed, as "C:\tools\Perl64".  The file that needs replacing is makefile inside the Image-ExifTool-X.XX folder.  After replacing, rung "nmake install" again.  This should install ExifTool on your machine.

QuoteDo you use your ActivePerl installation for other things than ExifTool?

No.  Installed it this morning, specifically for this.

Thanks.




obetz

depending on your requirements, this might be roo much effort.

You don't need a complete Perl just to run ExifTool!
And you usually don't need to "install" ExifTool with nmake to use it with an already installed perl, it's enough to unpack the files and run exiftool. If you preserve the directory structure, it will find it's modules.

What do you want to achieve specifically / what do you want to improve compared to the standard ExifTool distribution?
If I know your goals, I can suggest a suitable approach.

Currently, I provide for testing:
https://oliverbetz.de/exiftool-11.52_with_tests.zip unpack somewhere and run
https://oliverbetz.de/exiftool_install_11.52_Inno.exe Inno Setup based installer
https://oliverbetz.de/exiftool_install_11.52_NSIS.exe NSIS based installer with less options

Please excuse false positives from dumb virus scanners. If you are afraid, use the ZIP version.

These versions are based on Strawberry Perl so there might be differences. But it ran the selftest without any problem.

Strawberry Perl seems to provide best Windows support these days.

If you are interested in more (technical) background information and sources: https://oliverbetz.de/pages/Artikel/Portable-Perl-Applications see also https://exiftool.org/forum/index.php/topic,10128.0

allsan8

QuoteWhat do you want to achieve specifically / what do you want to improve compared to the standard ExifTool distribution?

I use several programs that use ExifTool.  ExifToolGUI is one.  Based on my experience, if one is using a standard normal account, one needs to run these programs with Admin privileges for ExifTool to work.  In some limited situations, I use the ExifTool command line.  And in my experience I have to run those with Admin privileges.  That is my primary reason for trying photogeek's instructions.

Thank you for responding.

I will try the Inno installer.


obetz

Quote from: allsan8 on June 21, 2019, 04:48:02 PM
Based on my experience, if one is using a standard normal account, one needs to run these programs with Admin privileges for ExifTool to work.

That's interesting. What was the result when you tried to run ExifTool as a restricted user (without admin privileges)? Where did you store ExifTool?

Let me know your opinion about the installer. User experience is the base of improvements, and there is certainly yet a lot to do.

Oliver