notepad-plus-plus icon indicating copy to clipboard operation
notepad-plus-plus copied to clipboard

Add option for updating Notepad++ at exit

Open xomx opened this issue 7 months ago • 24 comments

Fix #16601 , Fix #13749 , Fix #10317 , Fix #8495 , Fix #8457 , Fix #3755

npp-Pref-MISC-AutoUpdate-AtExit

xomx avatar Jun 03 '25 09:06 xomx

@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:

npp-GUP-UpdateAvailable-msgbox-at-exit

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)

xomx avatar Jun 03 '25 09:06 xomx

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.

image

image

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 avatar Jun 04 '25 20:06 ehawman-rosenberg

@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 silently checkbox 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.


EDIT - fixed binary artifacts for testing: x64 , x86

xomx avatar Jun 05 '25 10:06 xomx

Makes sense to me! Thanks again.

ehawman-rosenberg avatar Jun 05 '25 16:06 ehawman-rosenberg

@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 avatar Jun 05 '25 18:06 donho

@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 avatar Jun 05 '25 18:06 xomx

@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 avatar Jun 05 '25 19:06 donho

@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

xomx avatar Jun 05 '25 20:06 xomx

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 😛

ehawman-rosenberg avatar Jun 05 '25 20:06 ehawman-rosenberg

@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?

donho avatar Jun 05 '25 20:06 donho

@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.

donho avatar Jun 05 '25 21:06 donho

Oh this is a fun intersection of lesser-used English and tech jargon. The original definition of "gist" is

the main point or part : essence the gist of an argument

@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.

ehawman-rosenberg avatar Jun 05 '25 21:06 ehawman-rosenberg

@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_PARAM instead

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 avatar Jun 05 '25 23:06 xomx

@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 avatar Jun 07 '25 18:06 donho

@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...)

xomx avatar Jun 07 '25 21:06 xomx

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 avatar Jun 08 '25 13:06 donho

@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:

npp-Pref-MISC-AtExit-layout

Do you like the "At exit" or should it rather be "On close"?

xomx avatar Jun 08 '25 21:06 xomx

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:

image

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 avatar Jun 09 '25 18:06 donho

@donho

the combobox contains 3 values:

Ok, auto-update UI switched to combobox

_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).

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 avatar Jun 10 '25 01:06 xomx

@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 avatar Jun 11 '25 00:06 donho

@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 avatar Jun 11 '25 07:06 xomx

@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 avatar Jun 12 '25 02:06 donho

@donho Ok. I am on a short mountain trip. Will be back on this in 2-3 days.

xomx avatar Jun 12 '25 06:06 xomx

@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?

xomx avatar Jun 15 '25 02:06 xomx

@donho

  • Add new parameter "relaunchNppAfterSilentInstall" for the installer.

  • Add the translation

All done.

Thanks for handling the WinGUp update part.

xomx avatar Jun 20 '25 13:06 xomx

@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.

xomx avatar Jun 21 '25 03:06 xomx