Add option for updating Notepad++ at exit
Fix #16601 , Fix #13749 , Fix #10317 , Fix #8495 , Fix #8457 , Fix #3755
@ehawman-rosenberg and whoever wants to participate in testing of this PR
Now this PR is in a testing phase only, in the code is hardcoded some N++ version value for GUP (to be able to always bring up the GUP update dialog), also the GUP itself will need a slight modification if this PR will be accepted:
For testing, you will need to download this PR GitHub Action artifact, here for the x64 Release Notepad++.exe binary:
https://github.com/notepad-plus-plus/notepad-plus-plus/actions/runs/15413907360/artifacts/3248546905
and replace your current (rename the original one to e.g. notepad++.exe.ori) N++ main executable C:\Program Files\Notepad++\notepad++.exe.
Then also open your %APPDATA%\Notepad++\config.xml file (backup it 1st to e.g. config.xml.ori) and check/modify the noUpdate item there:
<GUIConfig name="noUpdate" intervalDays="15" nextUpdateDate="20250617" atAppExit="no">yes</GUIConfig>
The nextUpdateDate has to be lower than your current comp date, e.g. "20250601" (06 01 ... June 1st), otherwise there will not be the GUP updater for testing the feature.
Try it with and without the new At exit option and let me know ok/bad.
(translation stuff will be added later if accepted)
Sorry for the delay, had a whirlwind of a Tuesday. Tested Win11 and it appears to be working!
One small hiccup is that saying "No" with atAppExist="no" updates nextUpdateDate, while saying "No" with atAppExit="yes" does not.
Functionally it's pretty much exactly what I was hoping for. Thanks so much!
If you wanted to, I think adding a little checkbox or button to the up-front GUP dialog that says "Update on Close" would be really nice, but of course we don't want it to look like a soundboard. Maybe replace "Never" with opening the Preferences to the appropriate location? Then the options would be more clear/persistent.
EDIT: Just to clarify, this would be a little extra thing. It totally works as is with the to-do's you covered above and making the nextUpdateDate consistent.
@ehawman-rosenberg
One small hiccup is that saying "No" with atAppExist="no" updates nextUpdateDate, while saying "No" with atAppExit="yes" does not.
Good catch! Fixed.
Functionally it's pretty much exactly what I was hoping for.
Ok, so I will update the PR heading post to invite more potential users to test & comment.
adding a little checkbox or button to the up-front GUP dialog that says "Update on Close" would be really nice, but of course we don't want it to look like a soundboard. Maybe replace "Never" with opening the Preferences to the appropriate location?
While it is possible to do so, it would encompass adding a new custom N++ WM message for the inter-process communication (GUP->N++). IMO not worth it. And with the At Exit option ON, it's even useless (in the same way as pressing the Never GUP-dlg btn now, as I've already explained above - a N++ wnd capable of receiving such msgs is not behind at the N++ exit time...).
... Preferences UI rearranging img ...
This is of course possible but with this I will wait for the possible project maintainer opinion, I'm trying to keep this PR as simple as possible.
... Preferences UI new
Update silentlycheckbox possibility img ...
Yes, I thought about such option. But it requires thorough simultaneous debugging of both N++ & GUP from my side to be sure there wouldn't be any problems. Maybe later, when I have more time.
Makes sense to me! Thanks again.
@xomx Sorry for being late on the party. I know it's a frequent requested feature. However, I don't see we can do it other ways than Chrome - and if you take the same method to download & delay the installation (have not yet seen your code), then it's a big no.
@donho
Chrome - and if you take the same method to download & delay the installation
Of course not, I read your previous POV on this in the relevant FR issues.
(have not yet seen your code), then it's a big no.
Then you will be surprised how simple my sln is.
tl;dr summary - I took the existing updating code before entering the N++ main msg-loop
https://github.com/notepad-plus-plus/notepad-plus-plus/blob/8435308b028e93dc99a9e88ddba089a544e6dc50/PowerEditor/src/winmain.cpp#L651-L705
and without any optimization, I also copied it after leaving the msg-loop (with some minor N++ exit-specific changes). The rest of the PR is for one more Preferences checkbox and its corresponding config.xml stuff.
@xomx
OK, I just read vaguely your code, and saw you use updateAtExit to have 2 scenarios - well played.
However, I'm wondering if it's what users want.
I really think the expected behaviour is: when Notepad++ is launched, a new update is detected, a question is asked and user chooses "Install after exit" - while Notepad++ is closed by users after its usage, the installation is processed on the background, silently.
Whereas the implementation of this PR cannot (or more precisely speaking, there's no way to) make the installation completely silent - the system will always ask user if they want to launch installer.
So I'm afraid, with all your coding effort, user will always complain about the post-update is not completely silent.
@donho
However, I'm wondering if it's what users want.
Apparently, it is:
Functionally it's pretty much exactly what I was hoping for. Thanks so much!
What is my gist from all the users' FR posts in the linked issues - "I'd like to have the N++ updates ON, just do not bother me at all at the N++ start, where I usually have something urgent to do 1st - that is why I just launched the app!"
They do not ask to make the updates completely silent (although many would probably welcome this option too) . They just do not like the current situation where N++ tells them that "update is available" but they must click to "No" in the YesYessilentNoNever-dlg and then wait another 14 days for the next GUP-prompt window.
Whereas the implementation of this PR cannot (or more precisely speaking, there's no way to) make the installation completely silent
IMO, I even see a way with this PR implementation (haven't really tried that yet, just a debugging observation & thought experiment).
user will always complain about the post-update is not completely silent.
I'd solve the update-at-exit FR requests 1st but if you want, I could try to add the complete "updates-silentization" to this PR too (?) So then there will be e.g. two new checkboxes in the Preferences>MISC, just like in the above mock-up pic: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/16626#issuecomment-2941361869
Personally I would love if there were no interruption whatsoever when launching the program, with or without an update. I'm there to type something, usually jotting something down that I'm holding in my head or dumping something from my clipboard.
The behavior of creating an update box after closing the program is completely acceptable for me. However, I can see others becoming annoyed by N++ lingering around past its welcome.
If I'm following your conversation correctly, the GUP contains both the "check for update" and "start the update" pieces, and N++ can't hand parameters to it or vice versa.
So an alternative of, say, showing an "Update Available" icon (✨) in the top bar next to ? (for manual post-launch updates) wouldn't work, correct?
You would need to do a significant amount of work to have GUP store the user's on-launch "Update on Close" response and have another GUP instance check that variable first (to pass the initial prompt and go to interactive/silent install)?
EDIT: I've been comment jumped 😛
@xomx
What is my gist from all the users' FR posts in the linked issues - "I'd like to have the N++ updates ON, just do not bother me at all at the N++ start, where I usually have something urgent to do 1st - that is why I just launched the app!"
OK, I think it's legit. But where is your gist then? When I go: https://gist.github.com/xomx I see: ***xomx doesn’t have any public gists yet. ***
I could try to add the complete "updates-silentization" to this PR too.
Hmm... very interesting. But how can you workaround the system popup for the application installation?
@ehawman-rosenberg Thank you for the confirmation.
So an alternative of, say, showing an "Update Available" icon (✨) in the top bar next to ? (for manual post-launch updates) wouldn't work, correct?
I don't really like this solution. So we will focus on current PR with the current update interface.
Oh this is a fun intersection of lesser-used English and tech jargon. The original definition of "gist" is
@xomx is saying "The essence of what these people want is this..."
Also I hear ya. If it can't happen it can't happen. I really appreciate y'all taking another look at least.
@donho
But where is your gist then?
Sorry I was not clear, @ehawman-rosenberg is right, these were just my own words trying to summarize how I feel when reading the user FR posts on this matter.
I could try to add the complete "updates-silentization" to this PR too.
Hmm... very interesting. But how can you workaround the system popup for the application installation?
Just did a quick test.
- I added one more (now hardcoded) param at the N++ wWinMain updater places (in this PR before & after the main msg-loop):
updaterParams += L" -unattended"; - added the same param parsing to the GUP project wWinMain and if detected, it simply skip the YesYessilentNoNever-dlg and directly use the
FLAG_NSIS_SILENT_INSTALL_PARAMinstead
Then I only see (at N++ start or end - depending on the AtExit checkbox):
- the NSIS installer downloading progress-wnd (can also be hidden)
- NSIS installer UAC-prompt (meanwhile it cannot be suppressed but I plan to also look at this later, see the https://github.com/notepad-plus-plus/notepad-plus-plus/issues/15182#issuecomment-2916190015
So - until our NSIS installer supports per-user installations and/or until the user installs N++ to a protected location (such as the standard %PROGRAMFILES%), the system UAC popup will always be there.
@xomx
So - until our NSIS installer supports per-user installations and/or until the user installs N++ to a protected location (such as the standard %PROGRAMFILES%), the system UAC popup will always be there.
Yes, I was talking about UAC popup - once we use installer for update usage, the totally silent update will never come true.
@donho
once we use installer for update usage, the totally silent update will never come true.
Yes, that's true. Unless we e.g. include an installation of some N++ system update helper service in the N++ NSIS installer.
I think that this PR should remain simple as is and cover only the originally requested installation on close. If I add the above mentioned -unattended option to suppress the YesYessilentNoNever-dlg, it can create a user confusion as "why suddenly there is that UAC-prompt at the N++ exit?!" (this is also an argument against the complete silentization - when there will be e.g. an regression/bug in the new N++ version silently installed, users could start to be bewildered as why suddenly their N++ doesn't work...)
Unless we e.g. include an installation of some N++ system update helper service in the N++ NSIS installer.
By helper service you mean a daemon-like background process right? Not mentioning that I don't like such idea, the UAC popup cannot still be avoid if the installation location is on System Protection Area like %PROGRAMFILES%. Or do you mean such service has already Admin privilege?
I think that this PR should remain simple as is and cover only the originally requested installation on close. If I add the above mentioned -unattended option to suppress the YesYessilentNoNever-dlg, it can create a user confusion as "why suddenly there is that UAC-prompt at the N++ exit?!"
Yes, I feel the same way.
-unattended argument is useful only when the UAC popup can be removed, and we can make whole installation completely silent. Otherwise, don't bother to implement this option.
@donho
By helper service you mean a daemon-like background process right?
Yes.
Or do you mean such service has already Admin privilege?
Yes, this. A standard Windows system service, a list of which can be viewed by e.g. running the "services.msc". Here is the short summary for such a way (I'm not saying we're going down this path, now just for the info):
- we write a tiny Windows system service module (easy, it is enough to write a small Windows console app with only the winmain() and the LPSERVICE_MAIN_FUNCTION callback func, nothing more)
- install this service from our already elevated NSIS installer by:
sc.exe create <npp-service-name> binPath= "<FullPathTo\npp-service.exe>" - now the main part, we move the current notepad++.exe wWinMain update-checking code to that new npp-service.exe module
- and that's it, because now the code for checking for N++ updates (and possible launching of the NSIS-installer) will be run with SYSTEM privileges, so no UAC popup will appear...
Yes, I feel the same way.
Ok. So let's proceed to finalizing this PR. Do you like the current Preferences>MISC UI or should I change it or rearrange somehow? This is the current layout, there is IMO still enough space for the translations:
Do you like the "At exit" or should it rather be "On close"?
Yes, this. A standard Windows system service, a list of which can be viewed by e.g. running the "services.msc". Here is the short summary for such a way (I'm not saying we're going down this path, now just for the info):
I see. But personally I don't like this idea, not only do I try to keep the simplicty of application - but I believe also users don't want to see more (useless?) processes stay in the memory. As a result, it's unlikely to be implemented.
Do you like the "At exit" or should it rather be "On close"?
I think it would be better to change as "system tray" and "rendering mode", but with the label and combox reversed:
and the combobox contains 3 values:
Auto-updater: Disable
Enable on Notepad++ startup
Enable on Notepad++ exit
_nppGUI._autoUpdateOpt._doAutoUpdate won't be boolean anymore, but rather a integer (or enum if you prefer) which will contains 0 (disable), 1 (Enable on Notepad++ startup), 2 (Enable on Notepad++ exit).
The retro-compatibility should be kept, so we keep read "noUpdate" on startup for the convertion, and read & write new entry "autoUpdater" with value 0, 1 or 2.
Do you think it's OK, or you have other suggestions?
@donho
the combobox contains 3 values:
Ok, auto-update UI switched to combobox
_nppGUI._autoUpdateOpt._doAutoUpdatewon't be boolean anymore, but rather a integer (or enum if you prefer) which will contains 0 (disable), 1 (Enable on Notepad++ startup), 2 (Enable on Notepad++ exit).
Done.
The retro-compatibility should be kept, so we keep read "noUpdate" on startup for the convertion, and read & write new entry "autoUpdater" with value 0, 1 or 2.
Done. Code tested with the older configs and ok.
I've already removed from the PR the temporary hardcoded fake version value for the GUP, so now to test - there has to be a real newer N++ version available on the net.
If you think that all is ok, I will add the translation strings.
Also I am going to do a small fix for the GUP project (it will disable the "Never" button in the YesYessilentNoNever-dlg in case that there is no N++ wnd behind for receiving that command msg).
@xomx Just tried the new feature of the PR, works as expected (as a dev), but only one thing (as a user): While users choose "Enable on Notepad++ exit", what they want, IMO, is after clicking on "Yes Silently" and few popup, there's no Notepad++ relaunched. It's not the case. Though it's as expected for dev, I am wondering if it's as expected for users. If the most users don't expect relaunch of Notepad++ after updating on exit, we should modify the NSIS script in this PR, and modify WinGUp as well, it can be included in the next version. What do you think?
@donho
While users choose "Enable on Notepad++ exit", what they want, IMO, is after clicking on "Yes Silently" and few popup, there's no Notepad++ relaunched.
Very good assumption, I agree. If someone intentionally closes an app, they most likely want it to stay closed.
What do you think?
I remembered this request a while ago: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/15280#issuecomment-2246816010
"... I would like to automatically re-open npp only if the installation closed it, but if it was already closed it should not open it."
So what if we only modify the N++ installer NSI-scripts to always remember if there was a simultaneously running notepad++.exe instance at the installer time? The N++ mutex detection part is already there anyway. Then use simple logic - restart N++ at installer exit only when such a previously running instance was detected. With the new N++ autoupdate-on-close selected, there will not be any N++ instance running at the installer time, so also no N++ relaunch...
@xomx
So what if we only modify the N++ installer NSI-scripts to always remember if there was a simultaneously running notepad++.exe instance at the installer time? The N++ mutex detection part is already there anyway. Then use simple logic - restart N++ at installer exit only when such a previously running instance was detected. With the new N++ autoupdate-on-close selected, there will not be any N++ instance running at the installer time, so also no N++ relaunch...
Sorry, I don't really follow you - could you elaborate ?
@donho Ok. I am on a short mountain trip. Will be back on this in 2-3 days.
@donho
Sorry, I don't really follow you - could you elaborate ?
Just submitted a patch that illustrates what I meant.
It will solve both your described problem:
While users choose "Enable on Notepad++ exit", what they want, IMO, is after clicking on "Yes Silently" and few popup, there's no Notepad++ relaunched. It's not the case.
and the user request in the https://github.com/notepad-plus-plus/notepad-plus-plus/pull/15280#issuecomment-2246816010
Is that ok for you?
@donho
Add new parameter "relaunchNppAfterSilentInstall" for the installer.
Add the translation
All done.
Thanks for handling the WinGUp update part.
@donho Ok, done, please check for any errors in logic I could insert into the code or if I have forgotten something from your ideas.
I moved also the Date today(0); ... check into the launchUpdater(...) and change that new func to return bool for detecting the need to update the config.xml at the on-exit case.