flyakite
10th July 2004 18:25 UTC
Have installer choose dialog button to select?
Okay I'm trying to replace system files with the installer. However when a file is replaced the WFP (Windows File Protection) dialog comes up:
http://www.portraitofakite.com/images/WFP1.gif
So I moddified the CloseIE plugin code to close the window:
closeWFP
loop:
FindWindow $0 "" "Windows File Protection"
IntCmp $0 0 done
IsWindow$0 0 done
System
::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'
Sleep 300
Goto loop
done:
>FunctionEnd
>
It closes THAT window but when that window is closed this window is brought up:
http://www.portraitofakite.com/images/WFP2.gif
What code would I need to insert into that function to have the installer automatically choose "Yes" for the user? I imagine it's some sort of SendMessage command but I don't know what to send it.
Thanks in advance.
Comm@nder21
10th July 2004 19:35 UTC
you could search the handle of the "yes" button, and send a message to it, that fakes a mouse-klick.
or is there even a way to send a message like "yes"?
flyakite
11th July 2004 07:46 UTC
Hmm... okay I'm still having major problems. I've tried a million things so far and just can't get that second dialog to go away.
I think that the second dialog is like a child window or something. When the second dialog comes up the first one technically doesn't close. It just loses permanent focus and the new dialog becomes in focus.
I've discovered this code will send the 'y' key to a window which essentially is the same as click "Yes":
SendMessage $1 ${WM_CHAR} 0x79 0x230001
However I can't get the stupid HWND of that new dialog.
Can someone please tell me either how to get the HWND of that dialog or how to send a message to the window in focus, or how to get the HWND of the window in focus?
This problem is really bugging me and I'd appreciate any help.
deguix
11th July 2004 08:38 UTC
By the information I acquired now, you can use FindWindow from NSIS to do that. But how?
FindWindow $0 "#32770" "" $HWNDPARENT
If you give the window class and the window parent hwnd, it will output the first child window handle. I don't know if it will work but I tested here recently a code just like that above.
flyakite
11th July 2004 09:13 UTC
Okay it turns out this whole time the FindWindow code was working for both windows, as I added a message box to display the HWND of each one and it's working.
Now the only problem left is to simulate actually pressing the "Yes" button.
So far the
SendMessage $1 ${WM_CHAR} 0x79 0x230001
is not working. I've tried WM_KEYDOWN. Should I be using a command other than WM_CHAR? I know if the window is active and you just push the letter 'y' on the keyboard it selects the "Yes" button. And 0x79 is the hex code for the letter 'y', but after execution the window still remains.
This is the last hurdle I have, and have spent hours searching and trying different things to get it to work. There needs to be a function that just simulates a keypress and nothing else, independent of passing HWND parameters and whatnot.
deguix
11th July 2004 15:22 UTC
Windows has both "y" and "Y" letters. You have to find the code for letter "Y" as "Yes" has the first letter in upper case.
flyakite
11th July 2004 17:54 UTC
YES! I figured it out!
I appreciate everyone's help but unfortunately nothing that anyone suggested was working. But I stumbled across a post at www.experts-exchange.com for someone requesting their C++ project automatically hit an 'OK' button.
They were using WM_COMMAND to post a message using a call to the system library user32.dll, sending it the command of the button ID. They linked to a little app called MessageSender that allows you to test things like sending and posting messages to dialogs using different commands.
http://www.google.com/search?hl=en&ie=UTF-8&q=MessageSender
Anyway... for those interested, here is the complete code I use to close both windows automatically by virtually pressing the dialog buttons:
closeWFP
;Find and close first dialog
FindWindow$0 "" "Windows File Protection"
System::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_COMMAND},2,0)'
;Find and close second dialog
FindWindow$1 "" "Windows File Protection"
System::Call 'user32::PostMessageA(i,i,i,i) i($1,${WM_COMMAND},6,0)'
>FunctionEnd
>
So to close just one dialog you just need two lines of code:
1)FindWindow $0 "" "Windows File Protection"
2)System::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_COMMAND},2,0)'
The first line finds the HWND of the window with the title "Windows File Protection" and stores it as $0
The second line uses the system plugin and uses the call function. The only parameters you need to worry about are the ones in the last parenthesis ($0,${WM_COMMAND},2,0)
- $0 = The variable that we stored the HWND from FindWindow
- ${WM_COMMAND} = leave as is
- 2 = The ID of the button you want to press. In this case the "Cancel" ID is 2
- 0 = leave as is
Joost Verburg
11th July 2004 22:12 UTC
You should never try to upgrade protected files.
It depends on the Windows installation whether this message is displayed or not, if the file is cached it will be replaced back immidiately and you can't do anything to avoid that.
There is however no need to upgrade protected files, these files are automatically updated with Windows Updates and Service Packs. You can include signed Microsoft updated if you want.
If the problem is that you don't know how to check for file protection, a solution will be available soon. This week I will upload an entirely new system for installing/registering/checking/sharing DLL and TLB libraries.
flyakite
11th July 2004 22:46 UTC
lol, thanks for the advice but the entire purpose of the installer is to replace system files with moddified versions containing different icons.
The installer won't replace a file if the version in the installer and the version on the target computer won't match. The installer kills explorer. It then deletes the file being replaced from all the cache locations. To install all you have to do is rename the file on the system and then extract the file from the installer to the desired location, instead of renaming on restart.
I've done this successfully on hundreds of users computers and it's only not worked on a few because of the user, not the installer.
I've attached the script in case anyone is interested.