Interrupting display of command-line help text

Started by stan, August 09, 2024, 10:56:49 PM

Previous topic - Next topic

stan

Double-clicking the EXE (am using the latest Strawberry Perl-based ZIP release) opens a new window that displays the help text as usual with a pause after each page. Ctrl+C makes the window go poof! as expected.

However, typing exiftool at the command-line (cmd) and pressing Ctrl+C makes the program exit immediately with the following message:

^CCan't spawn "cmd.exe": No error at drive:\full\path\to\exiftool.exe\exiftool_files\exiftool.pl line 7526.
Perhaps not a bug, but really seems like something that can be handled better.

P.S. It seems exiftool doesn't clean up after itself, and leaves the %TMP% folder littered with exiftool_ver_doc.txt files?

Phil Harvey

Thanks for this report.  I'll look into it.

You're right about leaving the txt files in the TMP folder, but this is much better than the previous package which unpacked all of the modules there as well.  I could maybe delete the txt file but then ExifTool would have to re-create it each time rather than just generating it once.

- 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 suggest to create the help text during building the package and bundling it with the other files. No need to create it dynamically in the temp directory

Phil Harvey

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

stan

#4
I may have found a clue towards the cause of this bug in this StackOverflow answer:

QuoteMake sure your perl 32/64bit version and your starting cmd version match.

I had the same problem, and for me It was executing a 64-bit perl version inside a 32-bit cmd.exe.

Then, the perl script tried to do a system call, and at that point, it failed with the Can't spawn "cmd.exe" message.

When using a 32-bit perl, all worked.
As indicated above, it seems there might be a 32/64-bit mismatch somewhere, because when I tried the 32-bit ExifTool ZIP package and pressed Ctrl+C while the help text was being displayed, that error didn't show up!

On 64-bit Windows whenever I open a command prompt (not the newer Terminal or PowerShell), the 64-bit cmd.exe runs by default. Inside this Oliver Betz's 64-bit ExifTool launcher is executed by me. However, does the 64-bit ExifTool package bundle 64-bit Strawberry Perl by default, or do both the 32 and 64-bit ExifTool packages bundle the same 32-bit Strawberry Perl version?

Wherein lies the bitness mismatch, and why does the 32-bit version not show me the error on 64-bit Windows, while the 64-bit version does? :o ???

Phil Harvey

The 64-bit launcher runs a 64-bit perl.

I'm guessing the difference is that you may have 2 different versions of CMD on your system, and you may be running a different version when you open the CMD window manually vs when you double click on ExifTool. ?

Note that newer ExifTool versions no longer create the temporary .txt file.

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

stan

Quote from: Phil Harvey on October 19, 2024, 09:31:01 PMI'm guessing the difference is that you may have 2 different versions of CMD on your system, and you may be running a different version when you open the CMD window manually vs when you double click on ExifTool. ?
64-bit Windows does have 2 different versions of cmd.exe:

1. 64-bit cmd.exe at Windows\System32\cmd.exe
2. 32-bit cmd.exe at Windows\SysWOW64\cmd.exe

(About the inverted folder names, don't ask. ::) Or rather, ask MS about backwards compat.)

Anyway, whenever I open a command prompt window or double-click ExifTool.exe, Task Manager confirms that by default it's the 64-bit Windows\System32\cmd.exe that is running. So why the difference between the 2 ExifTool packages?

Maybe the script's system() call is invoking the 32-bit cmd.exe by mistake? That could explain why the 32-bit version succeeds with no bitness mismatch, but the 64-bit version fails.

Is there a way for me to edit the .PL file to print the full path to the current cmd.exe under which Perl/ExifTool are running?

Quote from: Phil Harvey on October 19, 2024, 09:31:01 PMNote that newer ExifTool versions no longer create the temporary .txt file.
Saw that there's now a copy in the ExifTool_Files folder by default. Good suggestion by Oliver there. :)

Phil Harvey

I've sent an email to Oliver hoping that he can weigh in here.

- 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 aware that cmd resp. terminal is invoked when starting ExifTool by double-clicking.

BTW, on (current versions of) Windows 11 it's no more cmd.exe but Windows Terminal.

I can terminate the exiftool help also from a terminal window by typing Ctrl-C

I would need to get to a Windows 10 system to investigate this issue.

FrankB

#9
I couldn't resist looking into this.


Quote from: obetz on October 20, 2024, 01:06:15 PMI wasn't aware that cmd resp. terminal is invoked when starting ExifTool by double-clicking.

See a screenshot from Process Explorer.
Explorer calls Cmd. Cmd Calls Conhost and ExifTool, Exiftool does a 'more windows_exiftool.txt' and that in turn calls cmd that calls more.

x64.jpg

Quote from: obetz on October 20, 2024, 01:06:15 PMBTW, on (current versions of) Windows 11 it's no more cmd.exe but Windows Terminal.

I can terminate the exiftool help also from a terminal window by typing Ctrl-C

I would need to get to a Windows 10 system to investigate this issue.

I can confirm the difference between Windows 11 and Windows 10.
On Windows 10, the 32 bits, the 64 bits and the 'old' perl-packer version show this 'Cant spawn' message.
On Windows 11, it does not.

I think the difference is the errorlevel being set. I created this cmd file and saved it in the ExifTool directory as 'more.cmd'. So it will get executed in stead of the normal 'more.com'

on break goto L10
c:\windows\system32\more.com "C:\Program Files\ExifToolGUI\exiftool_files\windows_exiftool.txt"
:L10
echo %errorlevel%


Windows 10: Gives an error level -1073741510

  Copying
    exiftool [*OPTIONS*] -tagsFromFile *SRCFILE* [-[*DSTTAG*<]*SRCTAG*...]
    *FILE*...

^CTerminate batch job (Y/N)?

C:\Program Files\ExifToolGUI>echo -1073741510
-1073741510

Windows 11: Gives errorlevel=0

DESCRIPTION
    A command-line interface to Image::ExifTool, used for reading and
    writing meta information in a variety of file types. *FILE* is one or
Terminate batch job (Y/N)?

C:\Program Files\ExifToolGUI>echo 0
0

BTW: The preferred way of closing 'more' is simply 'Q'. It will stop nicely.

@Oliver: I have Windows 11, 10, 8 and 7 versions. If you want me to do some tests let me know.

Frank

Edit: Notice that the echo %errorlevel% in the cmd file resets the errorlevel to 0. And the message no longer appears. Not even on Windows 10.

FrankB

@Oliver

I am able to reproduce the 'Cant spawn' message in Windows 11 by setting the 'Default profile' and 'Default terminal application' in the 'Terminal setup'.

(So you dont need Windows 10 perse)

setup.jpg
cmd prompt.jpg

FrankB

Looking closer at the options I noticed at the 'Actions' tab that ctrl+c is defined as Copy text. When you remove that you get the same behaviour in Windows 11 Terminal.

So my conclusion: Ctrl/C always triggered this message. In older windows versions, older Exiftool versions. Even in Windows 11 with Terminal enabled this message can appear, if CTRL/C is not used to copy to the clipboard.

What to do next? If you ask me: Nothing. Just learn to use Q to quit.
If it needs to be addressed then maybe calling 'SetConsoleCtrlHandler', or 'SetConsoleMode' in the ExifTool launcher could do the trick.

Frank

ctrl-c.jpg

Phil Harvey

Thanks Frank.

One thing to keep in mind is that ExifTool itself traps ^C while processing to clean up temporary files.  Any changes to the ^C handling should be tested to make sure this cleanup still occurs.  You shouldn't see any files named "FILE_exiftool_tmp" after interrupting a write process.

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

stan

#13
Quote from: obetz on October 20, 2024, 01:06:15 PMBTW, on (current versions of) Windows 11 it's no more cmd.exe but Windows Terminal.
As per my understanding, apparently cmd.exe is a command-line interpreter/command processor shell for WinNT, and the counterpart of the older command.com in DOS/Win9x. cmd.exe interacts with the user through a command-line interface implemented through the Win32 Console, which used to be conhost.exe but has now been replaced as the default with Windows Terminal since Win11 22H2.

In short, Win11 still has conhost.exe and cmd.exe, but I guess it now uses wt.exe (Terminal) and powershell.exe as the default console host and shell respectively. As Frank noted above, it seems both can still be switched back, so doing that or getting rid of Terminal's Ctrl+C redefinition for copy text results in the same error message as before. From what I've read it seems to me this isn't really a surprise since the real cause seems to be a possible bug in Perl itself (and not a bitness mismatch as I thought initially).

Pressing Ctrl+C apparently generates exit value 0xC000013A / STATUS_CONTROL_C_EXIT / 3221225786 / -1073741510 (signed 2's complement - this is the value printed by Frank's more.cmd above). As pointed out in these ancient forum posts and this old StackOverflow answer, Perl's win32.c source file (still!) seems to have a bug in such that if you use the built-in system() function to spawn an executable, and that executable then returns a negative exit value, Perl erroneously assumes that the spawn didn't work and spews out an erroneous Can't spawn... message.

Possible workarounds and/or fixes:

  • Comment out use warnings; - As far as I can tell this is useful more for developers who'll be editing the exiftool.pl script itself, to help them catch erroneous/unsafe code. Will commenting it out cause any potential issues for end users who're simply going to use the tool as-is?
  • Handle the negative exit value returned to system() somehow.
  • Stop relying on system() and external utilities such as more.com on Windows, and use Perl code itself to print the help text file.
  • File a bug report and hopefully get the issue fixed in the Perl source itself.

Phew, I didn't realize a simple observation of a spurious message would lead to such a detailed investigation by many! ::)

obetz

Thanks stan and Frank for the detailed investigation.

Fixing the problem in Perl itself seems to be the cleanest way, but might take a while.

We could also consider using a tiny wrapper around "more" to catch the negative return value (errorlevel).

I currently don't have much time to participate, but I try later in the the week.