Archive: Closing IE Windows


Closing IE Windows
  Hi all

It's been a while since I've been here or used the NSIS installer, but since I have started again I have found a new problem.

I have looked at all the methods for closing windows, and examples show how it works with Winamp, but when I try everything I can think of with FindWindow, etc I just cant get the IE Window to close.

Actually I want to close all open IE windows so perhaps a loop is required, but I have even seen examples of that.

If anyone knows if and how this can be achieved I would be most grateful.

Thanks

Simon H


Try this search:
http://forums.winamp.com/search.php?...der=descending

As I have mentioned in each one of those threads, it's never a good idea to terminate Explorer/Internet Explorer. There is always a better way of refreshing it for the change you have made. So, what's your change?


What I have is a customer with 2 proxy servers, and I'm writing an app using NSIS to change the proxy settings based on a commandline parameter in the shortcut to the proposed NSIS App.

So...when the user clicks on the link it closes existing windows, changes the proxy settings and re-opens IE.

I would find this tidier than leaving windows open that cannot access the pages that they were previously at, because of proxy settings, rather than leave dead windows open in the background.

Is there an easier way?

I will read that other post too, but probably have already!

Thanks

Simon H


No further ideas on this?

Simon


Well, at least on Windows XP SP1 with IE6, all open IE windows automatically get a proxy server change. I opened 5 windows and changed that setting (to a bogus server) in one window and tried browsing to google in one of the other windows. Did not work because the proxy setting was read by all open windows.

Probably doesn't help you, but on XP with IE6, there is no need to close the windows.


I have a little macro in one of my installers which might be of interest. See the attachment. The coding is pretty poor but I've never needed to improve it for that installer so I never bothered. Strictly speaking the macro could use offset jumps instead of labels which would be much better.


Originally posted by jthompson
Well, at least on Windows XP SP1 with IE6, all open IE windows automatically get a proxy server change. I opened 5 windows and changed that setting (to a bogus server) in one window and tried browsing to google in one of the other windows. Did not work because the proxy setting was read by all open windows.

Probably doesn't help you, but on XP with IE6, there is no need to close the windows.
This is true, and lesser versions also. The problem is that if a user is browsing an inTRAnet with 1 proxy setting, and then they change it (for intERnet) in a different window, they may still go back to the other window and continue to (try) and browse the inTRAnet. That would be confusing for joe user who know nothing.

Thanks for the input tho!

Originally posted by Sunjammer
I have a little macro in one of my installers which might be of interest. See the attachment. The coding is pretty poor but I've never needed to improve it for that installer so I never bothered. Strictly speaking the macro could use offset jumps instead of labels which would be much better.
Thanks Sunjammer! (Good to see you're helping NSIS a lot!!!..you've been busy!)

I have tried a variation of your attachment, from your Archive "Useful Functions" bit of the website, but with no joy.

Here is what I have now:

Function CloseProgram 

Exch$1
Push$0
loop:
FindWindow $0 $1
IntCmp$0 0 done
IsWindow$0 0 done
SendMessage$0 ${WM_CLOSE} 0 0
SendMessage$0 ${WM_QUIT} 0 0
SendMessage$0 ${WM_DESTROY} 0 0
Sleep 100
Goto loop
done:
Pop $0
Pop$1
FunctionEnd
>
I am calling it using:


Push "IEFrame"

>Call CloseProgram
>
The problem is that it locks IE, I lose the content, and the Menubar greys.

BTW I used Win32spy to get the class name (cool tool!!).

But this doesn't seem to actually close IE. I have also seen some C code for doing this, which may be useful in a DLL if you can make one, but haven't tested it yet. If you are interested I can email it to you.

Or if you have any further ideas on the code above, please let me know.

Thanks dude!

IE is a bit different in that it doesn't seem to want to close using SendMessage() calls.

The solution I've used to shut down all IE windows is to send a WM_CLOSE to the IE window using PostMessage(). Unfortunately, this API isn't natively supported by NSIS.

I believe there's an NSIS plugin that allows you to call API functions, and if not, it wouldn't be very difficult to build one that could just call PostMessage() for you.

Hope this helps,

Scott.


Originally posted by stereo
IE is a bit different in that it doesn't seem to want to close using SendMessage() calls.

The solution I've used to shut down all IE windows is to send a WM_CLOSE to the IE window using PostMessage(). Unfortunately, this API isn't natively supported by NSIS.

I believe there's an NSIS plugin that allows you to call API functions, and if not, it wouldn't be very difficult to build one that could just call PostMessage() for you.

Hope this helps,

Scott.
Here is a link to some CPP code that will kill process by name...maybe it could be used in a plugin (with the authors permission of course).

http://www.physiology.wisc.edu/ravi/software/killproc/

I can't compile nor do I know CPP, but if something can even be learnt from it then good.

Anyway...I still need to find a way to do it.

Thanks

BTW, I'm still using 1.98 I think, maybe 99, but havne't made the move to version 2 just yet!

Simon


System::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'

might work, assuming $0 contains the window handle as returned by FindWindow. If it doesn't work something similar should. I'd say consult the System docs in Contrib\System\System.txt but you'll need a Greek translator to help you :)


Originally posted by Sunjammer
System::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'

might work, assuming $0 contains the window handle as returned by FindWindow. If it doesn't work something similar should. I'd say consult the System docs in Contrib\System\System.txt but you'll need a Greek translator to help you :)
Can I use this in 1.98/9?

Errm good question. System was first distributed with NSIS in version 2.0b0 according to the release history. My improved plugin syntax became part of NSIS as of version 2.0a4 so the syntax would have to be that of the old CallInstDLL command, so you'd have to push the argument to the stack first... something like this:


SetOutPath $TEMP
GetTempFileName $1
File /oname=$1 system.dll
Push 'user32::PostMessageA(i,i,i,i) i($0,0x10,0,0)'
CallInstDLL $1 Call


I *think* that syntax is correct. Whether it will actually work? No idea. Anyway what are you using 1.98 for???

Originally posted by Sunjammer
Errm good question. System was first distributed with NSIS in version 2.0b0 according to the release history. My improved plugin syntax became part of NSIS as of version 2.0a4 so the syntax would have to be that of the old CallInstDLL command, so you'd have to push the argument to the stack first... something like this:


SetOutPath $TEMP
GetTempFileName $1
File /oname=$1 system.dll
Push 'user32::PostMessageA(i,i,i,i) i($0,0x10,0,0)'
CallInstDLL $1 Call


I *think* that syntax is correct. Whether it will actually work? No idea. Anyway what are you using 1.98 for???
LOL...cheers dude! I have just compiled my little thing in v.2.0b and it works ok.

I have also tried your system call but it only seems to cclose one window...just need to put it into a loop I guess.

I'll let you know how I get on, but this might work out ok!

Thanks again

You mean that System code I just concocted works??? Woohoo that was unexpected !!! :D


YEEEEEHHHH!!!!

It works dude..closes all IE windows :-)!!!

Here's the code (tested on Win2kpro only):


loop:

FindWindow $0 "IEFrame"
IntCmp $0 0 done
IsWindow$0 0 done
System
::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'
Sleep 100
Goto loop
done:
Thanks for the help!

Go on, you know you want to, do me a favour :D

Create a page in the Archive for that solution pretty please :)


no probs...glad to be of help!


Originally posted by simham_uk
YEEEEEHHHH!!!!

It works dude..closes all IE windows :-)!!!

Here's the code (tested on Win2kpro only):

loop:

FindWindow $0 "IEFrame"
IntCmp $0 0 done
IsWindow$0 0 done
System
::Call 'user32::PostMessageA(i,i,i,i) i($0,${WM_CLOSE},0,0)'
Sleep 100
Goto loop
done:
Thanks for the help!
I think I have a problem. I'm calling this in .onInit, then in .onInstSuccess I'm doing this:


onInstSuccess

ExecShell open 'iexplore.exe'
>FunctionEnd
>
My problem is, that on a Win98 machine I got it tested on, the new window didnt open in .onInstSuccess (it works from Start>>run ok).

Could it be, that because this machine is slow, the system call is STILL closing IE windows when the .onInstSuccess function is excecuted, therefore resulting in the system call closing THAT window too?

To ensure this is not the case, is there a way I can check that the system call has completely finished before proceding?

If not, perhaps you may have an idea to over come this anyway?

TIA

The system call could still be causing Windows to close, but it should only be those that were open when the system call was made. New windows would not receive the close message.

By the time .onInstSuccess is reached the loop of System calls has finished so the message definitely should not get sent to a new ie window that opens. (in my opinion, I might be wrong)

Have you tried other ways of running iexplore.exe? (e.g. a batch file, a shortcut, using the start command (Exec 'start iexplore'), using nsExec, etc.).


You are right Sunjammer. There is absolutely no way this loop closed that window. My guess is that the window never even opened. Try and see if you get an error after that ExecShell command (ClearErrors, ExecShell, IfErrors...). Maybe it can't find iexpolrer.exe for whatever reason.


Originally posted by kichik
You are right Sunjammer. There is absolutely no way this loop closed that window. My guess is that the window never even opened. Try and see if you get an error after that ExecShell command (ClearErrors, ExecShell, IfErrors...). Maybe it can't find iexpolrer.exe for whatever reason.
Thanks guys

I'll give it a try in the morning (afternoon :-) and see what happens...will let you know!

Originally posted by simham_uk
Thanks guys

I'll give it a try in the morning (afternoon :-) and see what happens...will let you know!
Just wondering...excuse my ignorance please if I'm talking rubbish, but since I have included the system DLL would it be possible to use this to open a window of IE?

AFAIK, there is no Windows API function that opens an Internet Explorer window. I bet there is some COM class you can use but I have no idea how to use those with System...


Well COM just involves calling CoCreateInstance and QueryInterface to get the object you want and then calling methods on it. I'm sure you can use the vtbl directly yourself to call them like you would C functions and so System might be able to do it that way. Not sure really.


Originally posted by Sunjammer
Well COM just involves calling CoCreateInstance and QueryInterface to get the object you want and then calling methods on it. I'm sure you can use the vtbl directly yourself to call them like you would C functions and so System might be able to do it that way. Not sure really.
It appeared to just be a stoooopid syntax thing...this works just fine:


onInstSuccess

ExecShell open"iexplore.exe" "" SW_SHOWNORMAL
FunctionEnd
>