- NSIS Discussion
- Custom dialog is displayed very slowly
Archive: Custom dialog is displayed very slowly
agaasbeek
9th January 2012 12:46 UTC
Custom dialog is displayed very slowly
Hi,
In my installer I display the MUI_PAGE_COMPONENTS to let the user make a selection. Now I added a custom page where the user can enter a database user name and password. So far so goed and the page is displayed fine. Notice that at this time the function that displays my page is placed/defined in the .nsi file before all the section code.
Now I wanted to only show this custom page whenever the user has selected the database component. So I use SectionGetFlags for this. The problem I now faced was that it always returned 1, no matter what the selection was. Then I moved the custom page function code after the section code, and suddenly the flag was correct! Is this normal behaviour, or am I missing something?
Although this works, another problem pops up, and that is that it takes about 30 seconds for the page to load after clicking on next in the previous page! I immediately see the header text, but the rest of the dialog keeps displaying the data from the previous dialog for about 30 seconds. When the dialog should not be displayed, the next page is displayed half for 30 seconds before being displayed correctly.
Does anyone know what the problem is or have suggestion on how to solve it? I have added my script (emptied the section, to have a more readable script).
Any help would greatly be appreciated.
Ad.
Afrow UK
9th January 2012 12:48 UTC
Firstly try switching to MUI2.nsh which is MUI but using nsDialogs instead of InstallOptions.
Edit: Your actual problem is moving the functions after the sections means nsDialogs.dll is at the top of the compression block which means it takes a long time to extract. As well as aforementioned modification, add a ReserveFile `${NSISDIR}\Plugins\nsDialogs.dll`.
Stu
agaasbeek
9th January 2012 13:35 UTC
Originally posted by Afrow UK
Firstly try switching to MUI2.nsh which is MUI but using nsDialogs instead of InstallOptions.
Edit: Your actual problem is moving the functions after the sections means nsDialogs.dll is at the top of the compression block which means it takes a long time to extract. As well as aforementioned modification, add a ReserveFile `${NSISDIR}\Plugins\nsDialogs.dll`.
Stu
Switching to MUI2.nsh did the trick and solved the slow loading. (only adding ReserveFile didn't work). Thanks!
Any ideas though on why the functions needs to be placed in the .nsi file after the sections? Is this normal behaviour and related to how nsis processes/interprets the file?
Ad.
Afrow UK
9th January 2012 14:44 UTC
Yes it is because SEC_DATABASES is not defined until after the section which defines it (it is just a regular !define containing the section index).
Rather than using SectionGetFlags etc. you can use:
${IfNot} ${SectionIsSelected} ${SEC_DATABASES}
Abort
${EndIf}
Stu
agaasbeek
10th January 2012 08:53 UTC
That is much cleaner code. Thanks a lot.
But ... I just found out that the 30 seconds delay is still present but now at the end after I press finish. The page goes white, it looks like it 'hangs' and then after about 30 seconds it closes. While I prefer to wait 30 seconds at the end instead of somewhere in the middle, I would rather not wait at all :-)\
The delay is also present when I don't select any components.
I do ReserveFile now, as you suggested, although the purpose of that was to speed up page loading and I guess it has nothing to do with closing the installer.
Any thoughts?
Ad.
agaasbeek
10th January 2012 10:04 UTC
I emptied all sections and the installer closes quickly. After putting the code back into 4 of the 7 sections, I again get a delay, but now only about 5 seconds.
So, apparently the more sections (or the more I do in them?), the bigger the delay gets. I don't select any components, so the sections are not executed.
Are there any general rules or do's and don'ts that I'm not aware of?
Ad.
Afrow UK
10th January 2012 11:12 UTC
It may be that you have WriteUninstaller in .onInstSuccess. I would move it to a hidden section. You could also try ReserveFile for the System plug-in.
Just a few notes for you.
- You are using Icon and MUI_ICON; you should only use MUI_ICON.
- You are using Page instfiles; you should use !insertmacro MUI_PAGE_INSTFILES (avoid mixing non-MUI pages with MUI pages).
- I see no RequestExecutionLevel instruction (it probably ought to be user). Without it you may have problems installing on Vista and above.
Stu
agaasbeek
10th January 2012 11:13 UTC
Ok, I find out which line causes the delay and I think also why but not how to get around it.
I have the following line inside a section:
File /r /x *.svn .\target\distribution.dir\distribution\*.*
Without this line, the installer builds much faster and the delay upon closing is gone. With this line included the delay is back. When the component is selected, then the delay at the end is also gone.
So, what happens is that the installer unpacks all these files and that causes the delay. When the component/section is selected, then the delay is ok, because it is just part of the installation of that component.
However, when the component is not selected and the section is therefore not executed, the installer apparently still unpacks all the files after pressing the finish button, hence the delay.
The question is why? And how do I solve this? Is there a better way than what I'm doing now?
Ad.
agaasbeek
10th January 2012 11:17 UTC
Quote:
I just missed your reply while I was typing my previous message.
I already tried removing WriteUninstaller but to no avail, but that is not a surprise when you take into account my previous post.
Will incorporate your suggestions though.
Ad
Originally Posted by Afrow UK (Post 2832375) It may be that you have WriteUninstaller in .onInstSuccess. I would move it to a hidden section. You could also try ReserveFile for the System plug-in.
Just a few notes for you.
- You are using Icon and MUI_ICON; you should only use MUI_ICON.
- You are using Page instfiles; you should use !insertmacro MUI_PAGE_INSTFILES (avoid mixing non-MUI pages with MUI pages).
- I see no RequestExecutionLevel instruction (it probably ought to be user). Without it you may have problems installing on Vista and above.
Stu
|
Afrow UK
10th January 2012 11:32 UTC
I suppose you could try putting a MessageBox in a leave function for the finish page (to pause before exiting) and then check the contents of $PLUGINSDIR (%TEMP%\ns*.tmp\*) to see if there are any DLL's in there that need reserving.
If you cannot solve the problem, just move the page functions back to before the sections and just hard-code the section index (or define SEC_DATABASE yourself).
Stu
agaasbeek
10th January 2012 13:11 UTC
Quote:
agaasbeek
10th January 2012 13:39 UTC
I found a work around for my problem. Simply by setting
SetCompress Off
The installer executable gets somewhat bigger, but the delay is gone, and that is much more important. The question still remains why the files get extracted, even when the installer does not need them because the section that copies them is not selected.
But for now it will do.
Ad.
Afrow UK
10th January 2012 16:48 UTC
It is just the way the compression works. I'm sure there are other settings which will help improve but you'd have to check lzma specifics. How big are the files? Also make sure no antivirus software is running.
Edit: Also can you attach your updated script?
Stu
agaasbeek
11th January 2012 06:06 UTC
Originally posted by Afrow UK
It is just the way the compression works. I'm sure there are other settings which will help improve but you'd have to check lzma specifics. How big are the files? Also make sure no antivirus software is running.
Edit: Also can you attach your updated script?
Stu
I still fail to understand why the installer starts extracting files at the end of the installation process when it is sure that the files are not needed and the only thing the installer has to do is close.
I have about 20 files with sizes in the range of 1 to 32 MB, with the average size being 11 to 12 MB. All other files have much smaller sizes like 5 KB or so.
I attached the script and emptied all sections but one. I marked/commented the line that causes the delay (when compression is turned on).
Ad.
agaasbeek
11th January 2012 06:40 UTC
I tried:
SetCompressor /SOLID lzma --> 30 seconds delay, installer exe of 225 MB
SetCompressor lzma --> no delay, installer exe of 237 MB
SetCompressor zlib --> no delay, installer exe of 246 MB
SetCompress Off --> no delay, installer exe of 256 MB
So, the /SOLID option compresses the best, but at the cost of a big performance penalty (in my case anyway).
EDIT: my previous post is still 'under moderation' and not shown.
Afrow UK
11th January 2012 12:37 UTC
I'm no expert on the matter but if the installer needs to access a file which has been compressed last, it needs to decompress the entire block that contains that file to access it. You should probably try and contact kichik if you want to know the real details (but he's not around much now). Maybe just avoid /SOLID then but this is not really a solution. I'm interested to play around with your script. Where can I grab the files to build it?
Stu
agaasbeek
12th January 2012 07:03 UTC
Many thanks for your time, suggestions and explanations!
My company does not allow me to put our own files on the internet, but I don't think you will need my files. I think any file of 20 MB or so will do, just copy it ten times, and then you will have a similar situation. The more files, the bigger the delay will be obviously. (The installer includes jre-win32.exe and apache-activemq.zip, 16 and 32 MB in size respectively, so you could download and use them).
Ad
Originally Posted by Afrow UK (Post 2832383) I suppose you could try putting a MessageBox in a leave function for the finish page (to pause before exiting) and then check the contents of $PLUGINSDIR (%TEMP%\ns*.tmp\*) to see if there are any DLL's in there that need reserving.
If you cannot solve the problem, just move the page functions back to before the sections and just hard-code the section index (or define SEC_DATABASE yourself).
Stu Moving the page functions back doesn't work. It turns out that both problems are not related. I just hadn't noticed the delay before because I never tested what happened when no component was selected.
In the pluginsdir only the system.dll is present, and reserving it does not help.
I can reserve all big .exe/.zip/.jar/.war files in the distribution that are copied with before mentioned "FILE /r ..." command, but that does just move the delay from the end of the installer to the beginning. When I then start the installer it takes 30 seconds before the first installer page is shown, so that is even worse. I found a similar topic (http://forums.winamp.com/archive/ind.../t-202654.html), but the main question there remains also unanswered.
So, no matter what I do, I can not prevent the extracting of files, even when the code that actually copies them is inside an unselected section and is not executed.
This behaviour seems very strange to me and I cannot believe that there is no solution for it. But unfortunately I cannot find it.
Any suggestions are still more than welcome!
Ad. |