nppShell
nppShell copied to clipboard
NppShell.dll is not released after N++ uninstall
While investigating notepad-plus-plus/notepad-plus-plus#15892 I found NppShell.dll is not released after N++ uninstallation, and after a fresh installation in e.g. c:\Program Files RMB Explorer contex menu is not working because old dll is loaded like so:
Running regsvr32.exe /s /u ... as admin also didn't help.
OK, some more info. It seems that the uninstall "sometimes" works. It uninstalled correctly on a Server running Windows Server 2025 (basically W11 server 24H2) with only one logged on user. On the server I found the issues on, that was Server 2022 ( W10 server ) and there were other users logged on which probably caused the inability to remove the dll. Not sure if there is any difference cause by W10 or W11, the dll does work differently I believe between the 2.
There is no safe way to unload a DLL from explorer (except terminating the process) - so there isn't really anything we can do. There are some hack around - but there is no safe way to do it.
Is it possible that NppShell.dll keeps opened some resources/handlers which block it from unloading when regsvr32.exe /s /u ... is executed?
No, but like I said, there is no safe way to unload it from explorer.exe . So even though it has no handles to any files open, it is still loaded into explorer until explorer restarts.
So explorer even is not trying to unload it on regsvr32.exe /s /u ... ?
I did try to add it, the only thing that happens if you try to unload it, is that explorer.exe will crash (due to the thread running the code dying), so 🤷♂️
The only thing that does is just call a function inside the DLL - we would have to implement it ourselves - it doesn't do anything for us, except call a function. Trying to unload the DLL where your own function resides with will cause the process to crash (like cutting the branch you are sitting on)
How about to let the DLL know to be aware of new N++ location? It's only a guess, because I don't know the architecture.
I don't see how that would unload the DLL from the explorer process?
I mean, keep the dll loaded, but make it work with new N++ location.
So you are installing notepad++ to a new location, when you are upgrading?
I'm not. Just reinstalling: uninstall then install again.
Then the location is the same? I am a bit confused as to what the issue is.
When the installer updates, it moves the old version away and places the new version in it's place. Next time explorer starts, it loads the new version.
No. New location is changing. I was testing the issue like this:
- Uninstall current version
- Install the same version but in new location.
Right now I'm not sure if an old dll is removed or left alone, but the issue is there is no way to unload the dll and load new dll to let it know about new location of N++.
My suggestion was to let loaded dll know about the new location of N++.
(FINAL edition v1 ;)
When you install it, it gets registered in the new location, so it should be loaded from there going forward.
Why do you want to tell the loaded DLL about the new install location?
To make Edit with Notepad++ in RMB context menu still works. Now after reinstall to another location, Edit with Notepad++ is showed but nothing happens after clicking it. My idea was that the new location of N++.exe is not updated somewhere, but it's only the guess and I might be wrong.
If I recall right, there is also no N++ icon next to Edit with Notepad++ so maybe the dll is not working anymore, as we discussed earlier and it's futile to update new location of N++ anyway.
That makes sense, since it uses it's own path to find the npp exe. This is such an edge case, I don't see a good way to fix it. If you want to work around it, restarting explorer solves the problem.
So explorer even is not trying to unload it on
regsvr32.exe /s /u ...?
Regsvr does not unload anything in other processes, it usually just edits the registry.
Shell extensions can be unloaded in theory when DllCanUnloadNow says so but for this to happen, something inside Explorer has to trigger a call to CoFreeUnusedLibraries and I don't think there is a message you can send to trigger this.