Archive: Type "x" when installation is in progress.


Type "x" when installation is in progress.
The installer I am working on has a test case where pressing the "x" key on the keyboard must not interrupt the installation when all the files are being unpacked and deployed to their final destinations.

However, when I pressed "x" whilst testing, the installer becomes unresponsive. :(

It continued to have a task bar entry, but clicking that does not bring the installer to the foreground. Checking the task manager showed that the installer was still running and using CPU time, but I was not able to switch back to it. It does sometimes become visible again if I press the Windows key + "D" a couple of times, but the contents of the installer window is not updating.

Is there a way to disable this feature?

The only way to stop the installer is to kill the process using the Task Manager or other similar tool.


I can't reproduce this. Please include more details. Which version of NSIS? What exactly is the installer doing when you press the X button? Is it the keyboard X button or the close button on the top right corner of the window?


I am using NSIS 2.26 (large string version). I am running Windows 2000 SP4.

As I said in the original posting, you press the "x" key on the keyboard - between "z" and "c" on a UK keyboard. I am not referring to the "x" button at the top-right of the window. This happens when the installer is on the MUI_PAGE_INSTFILES page.


Still can't reproduce this. Upgrade to 2.27 and provide a minimal script that displays this problem. If you can't provide a script, list the plug-ins that you use and any other detail that might be relevant. Also try reproducing it yourself on other computers.


Example installer...
I have created an example installer script. The script for it is included in the attached zip file.

The installer has 4 sections, and each section basically sleeps for one second allowing time for the user to press the "x" key. DetailPrint'ed instructions on when to press "x" are displayed.

This test installer does not perform any installation actions.

I have confirmed with a colleague that the installer also dies on his computer when they press x during install time.

Just to summarise again, I am using

NSIS 2.26 (large string version)
Windows 2000 Service Pack 4


Whatever the issue is, please first use NSIS 2.27 not NSIS 2.26.


Can't reproduce the defect you decribe compiled you example using 2.27 on Vista Ultimate. Installer just runs fine.

As I understand you want people to be able to cancel the installer? Why not have last custom page the with a button and text, like "Oeps, no it did not want to install, please uninstall"?

Note that sleep lets the installer sleep, i.e. the installer application unable to do anything. Maybe create a loop if you want to do certain other actions.

I do still not see what it is you really want to accomplish.


NSIS 2.27 does not help
I have the same problem with NSIS 2.27 (large string version).

Onad: I do not want people to be able to cancel the install.

The point is that pressing "x" crashes my installer. Why does this happen?

Did you press the "x" on the keyboard when the example installer instructed you to? I do not use the sleep command in my real installer. I had to use it for this demonstration to simulate a large number of files being unpacked.


unable to reproduce...
I compiled the sample script on NSIS 2.25 and ran it on XP sp2. The X key gave me the 'default beep' each time I pressed it, but the script completed normally.

I'll try this again at work where I have Win2K

Don

Edit: Originally I wrote that I compiled this on NSIS 2.26.


I can reproduce this with the example on Windows 2000 SP4, but not on Windows XP SP2... Wierd. This has "Windows api bug" written all over it. :D

Edit: And I used "normal" NSIS v2.27


Thanks {_trueparuex^}!! At last someone else who can reproduce this :-) I started to think that I had gone insane!!!!! ;)


reproduced again (Win2k, NSIS 2.23)
The CPU goes to full usage (50% on a dual processor) when I typed X. I'll try to attach the debugger and see what is happening.

Don
Edit: Debugging didn't show me much. The system appears to be looping inside USER32.dll, in the function SendMessageA


What happens next?
Are there any moves to resolve this issues? Does a bug need to be raised? Is there any idea on the time to get a fix for this problem?


I can reproduce it as well on Windows 2000 SP4. If you say it didn't happen with 2.25, it must be related to the disabling of the X button on the top right corner of the window when the Cancel button is disabled. I don't get how the `X` button on the keyboard is related as nothing in NSIS cares for anything on the keyboard but the space bar on the components page.

It'll take some debugging time and it's not the top priority right now. Any more details would be helpful. And yes, a bug report should be submitted.


I reported above that it was reproduced on NSIS 2.23 and Win2k SP4, it wouldn't be related to the cancel button in that case.

Don


Even stranger...


Re: reproduced again (Win2k, NSIS 2.23)

Originally posted by demiller9
Edit: Debugging didn't show me much. The system appears to be looping inside USER32.dll, in the function SendMessageA
It responds to any key pressed with a very nice endless loop in USER32!xxxGNM_FindNextMnem. It seems to have a loop around USER32!_NextControl which keeps returning more controls. When it gets to the last control, it goes back to the first one again.

And the stack trace...
be415c9c 8046950e nt!RtlpBreakWithStatusInstruction
be415c9c a003bced nt!KeUpdateSystemTime+0x13e
be415d3c a003bd84 win32k!InternalVkKeyScanEx+0x5c
be415d50 80465691 win32k!NtUserVkKeyScanEx+0x4b
be415d50 77e14e36 nt!KiSystemService+0xc4
0012fac4 77e304d6 USER32!NtUserVkKeyScanEx+0xb
0012fcf0 77e302ac USER32!xxxGNM_FindNextMnem+0xf6
0012fd18 77e17cf4 USER32!xxxGotoNextMnem+0x24
0012fd44 77e1cbd9 USER32!IsDialogMessageW+0x22a
0012fd80 77e1ca62 USER32!DialogBox2+0x14e
0012fda4 77e1cd18 USER32!InternalDialogBox+0xd1
0012fdc4 77e378af USER32!DialogBoxIndirectParamAorW+0x34
0012fdf0 00403793 USER32!DialogBoxParamA+0x4a
00407294 74696445 KillTheInstaller+0x3793
00407298 00413032 0x74696445
0040729c 68636952 KillTheInstaller+0x13032

I was able to workaround this Windows bug by removing the WS_GROUP style from the first button. I still don't know exactly what happens there, but at least a very good direction now.


Well, not even that works... There's a loop there that calls _NextControl until it finds a mnemonic for the pressed key. It also stops if the loop returns to the original dialog item that was enumerated first.

iWND xxxGNM_FindNextMnem(iWND dialog, iWND ctl, WCHAR key) {
// some other group(?) stuff here

// find control with matching mnemonic
iWND h = _NextControl(dialog, ctl);
while (h != ctl) { // never equal!
if (SomeMnemCheck(h, key)) {
return h;
}

h = _NextControl(dialog, h);
}
}
But _NextControl() never returns ctl, which for the specific call in which it hangs is the internal handle to the IDD_INSTFILES dialog. dialog is IDD_INST.

Heh, I managed to reproduce a similar bug in Windows XP SP2. In a dialog with no enabled or visible controls with WS_TABSTOP, sending WM_NEXTDLGCTL(0, FALSE) kills it :)


And here's a small reproduction program. I'll try to minimize it to see if I can pinpoint exactly what's wrong. Currently it seems like it's choking because the default button, which also has "focus" is invisible.


Some more fun debugging lines later and I think I have a mostly complete description of the bug.

  1. The user hits a key.
  2. Windows translates that to a WM_CHAR message to the focused control in the active window.
  3. That control is hidden, so it passes the message to its parent. The parent, in our case, is also a child of another dialog.
  4. DialogBox2 (which is internally called by our own DialogBox) reads this message using PeekMessage and calls IsDialogMessage to handle it.
  5. IsDialogMessage gets WM_CHAR and so it calls xxxGotoNextMnem to activate a mnemonic, if present.
  6. xxxGotoNextMnem calls xxxGNM_FindNextMnem which loops over all controls, starting from the control passed to WM_CHAR. It does that using _NextControl.
  7. _NextControl never returns the internal dialog because it has the WS_EX_CONTROLPARENT style. Instead, it returns its first child.
  8. xxxGNM_FindNextMnem keeps looping until it finds a control with a matching mnemonic or until it reaches back to control sent to WM_CHAR.
  9. xxxGNM_FindNextMnem never finds a matching control and _NextControl never gives it a proper value to stop the loop.
So to sum it up - don't set focus to a control and then hide it. Or, if you'd like, Windows dialogs love infinite loops. There are a number of places in the code I've debugged where loops are stopped with a counter that reaches magic values like 0x400. _NextControl itself calls _NextSibblingOrAncestor up to 0x400 times, probably to stop another infinite loop bug that was there in the past. Just for the laughs, I've debugged the same functions under Windows XP. And lo and behold, that exact piece of code now has a counter reaching to 0x400 as well! :D

Good god that isn't very good lol
Well done though kichik :)

Stu


http://sourceforge.net/tracker/index...49&atid=373085


Originally posted by kichik
Just for the laughs, I've debugged the same functions under Windows XP. And lo and behold, that exact piece of code now has a counter reaching to 0x400 as well! :D
So it loops somewhere 1024 times in XP too? :D Well that's one way to fix infinite loops.

By the way this bug is also reproducible on Windows 98 and (my guess) on any windows prior to XP.

Not only somewhere... A lot of places! :)