Archive: Feature request perhaps


Feature request perhaps
I have a feature request but I thought I'd ask you all about it first in case there is another way about it.

In the past few months I've written a number of plugins that modify existing NSIS pages (ScrollLicense, ToggleInstFiles etc) rather than create their own pages.

I've created a built-in Unload function which is called without /NOUNLOAD which puts the window procedures back to the originals and lets NSIS delete the plugin DLL (and $PLUGINSDIR folder).

The problem that I have is that there's no good way to unload the plugins. If you call the plugin Unload function from the Leave function, it crashes the installer which also occurs when calling it in the abort function (when user clicks Cancel). I'm guessing this is because the dialog is no longer in memory then?

So basically the problem is that I need to call this Unload function when the user leaves my modified page (Next, Back, Cancel) and before they close the installer. The best way that worked 100% for this was when using a Custom page and placing the Unload function directly under the InstallOptions::dialog call.

Now, my feature request would be for normal pages: Could a new optional parameter be added to the Page / PageCallbacks instructions to set a function which is called when the user clicks ANY of the Next, Back or Cancel buttons while the Page is still in view. Here I can safely call the Unload function.

Cheers!

-Stu


Maybe there is a place where the "/NOUNLOAD" was not used before this call or, like you said, plug-in problem which doesn't return something to NSIS control or something not freed after the plug-in is freed from memory. Maybe some code would clarify this more.

btw, there is a very old InstallOptions modification which supports to unload the plug-in using a function. If I remember right, it is a little buggy in this too.

EDIT:

Now, my feature request would be for normal pages: Could a new optional parameter be added to the Page / PageCallbacks instructions to set a function which is called when the user clicks ANY of the Next, Back or Cancel buttons while the Page is still in view. Here I can safely call the Unload function.
InstallOptions handles the "WM_NOTIFY_OUTER_NEXT" message. This message tells when a click is done on the next, back or cancel buttons. For me I don't see the reason for implementing an "unload" function if you can have a way to communicate with the user on the "leave" function to tell it it needs to be unloaded (i.e. using ini files for InstallOptions pages).

Ok thanks I'll have a look at WM_NOTIFY_OUTER_NEXT.

There is still the problem that the plugin needs to be called atleast once without /NOUNLOAD before closing the installer. Otherwise the plugin won't get deleted. It seems that NSIS doesn't unload a plugin when closing the installer and it only becomes deletable after you close the installer.

-Stu


It's odd - the ScrollLicense example file, for example, works perfectly - but within my larger file (sorry, can't post/provide - if I get time to narrow it down, I will) I do get a crash when the installer closes. Nasty one, too, DrWatson gets all confused by it :)

I've since resorted to storing the plugin dir in a temporary registry location and launching a second, silent installer that pauses for a few seconds at the end of the first installer. This second installer grabs the plugin directory from the registry, zaps its contents, then the dir itself (if empty), then removes the registry entry.


Yeh that's what I resorted to also when writing a plugin for a fellow NSIS member. The exe is ran in .onGUIEnd and deletes all ns*.tmp folders in $TEMP.

I'll have a look if I can fix the problem with ScrollLicense (and the others) because crashes are nasty :/

-Stu


Originally posted by Afrow UK
There is still the problem that the plugin needs to be called atleast once without /NOUNLOAD before closing the installer. Otherwise the plugin won't get deleted. It seems that NSIS doesn't unload a plugin when closing the installer and it only becomes deletable after you close the installer.
You can have the plug-in unload itself using a new thread and FreeLibraryAndExitThread.

Thanks kichik.
Here's the code that I've made but it doesn't seem to work.


HANDLE hNewThread;
HMODULE phModule = GetModuleHandle("ExitButton2.dll");

SetWindowLongPtr(hWndDlg, GWL_WNDPROC, (LONG)ParentWndProcOld);
SetWindowLongPtr(hWndDlg, DWLP_DLGPROC, (LONG)ParentDlgProcOld);
SendMessage(hWndDlg, g_uMsgCreate, FALSE, (LPARAM)hWndDlg);

CreateThread(NULL, 0, UnloadPluginThread, phModule, 0, NULL);

...

DWORD WINAPI UnloadPluginThread(LPVOID lpParam)
{
HMODULE hDll = (HMODULE)lpParam;
FreeLibraryAndExitThread(hDll, 0);
}

It doesn't crash which is a good sign, but it doesn't unload the plugin either.

Edit: Ok I see the problem. I need to pass the module MHANDLE as the parameter.

Edit #2: Updated code, still does not work (now it crashes too).

-Stu

Could you post again when/if you've updated the plugins?
I'd love to give it a try again and see if things don't crash with the new methods - the post-install deleter thing scares me a bit :)


*bump* :)

-Stu


bump ? Not seeing the update - am I being too eager? ;)

oh, I'm blind. nevermind me.

I second the bump - Kichik ? :)


Why not call the Unload function in .onGUIEnd like with BgImage? That callback function is executed after the dialog is ended. That means no further window messages will be processed.


That works lol
I didn't like the fact that my window procedures would still be in use until you close the installer, but I guess that'll just have to be... shouldn't cause any problems hopefully.

Uploaded ScrollLicense and ToggleInstFiles which both use .onGUIEnd to Unload in the examples.

-Stu


that works :D Thanks to both of you :)