File Content Vanishing?
I am working on software that allows a user to edit various sections of a complex INI file. I use Notepad++ to look at the actual settings and values in the file before my tools read and after my tools write the file [using functions like GetPrivateProfileString()].
Every once in a while, after the file is updated [with WritePrivateProfileString()], Notepad++ does not appear to detect the change and when I try to change/save the file in Notepad++, a message is displayed that Notepad++ doesn’t have permission to write to the file (even though it had just done so less than a minute earlier) and offers to restart under the Administrator account. When I reject that offer and close Notepad++, the INI file size has become ZERO and nothing sees ANY of the 19KB of data that had been there a moment earlier.
I like Notepad++ because of both syntax coloring and change detection, but I cannot have these files being silently truncated to zero length like this!
That’s interesting because there exists a well known issue of file content deletion in Notepad++ at least up to v7.7.1. The new version 7.8 should contain a fix for that problem. But its developer @pnedev was not able to create a testing scenario to reliably reproduce the issue. Seems like you have found a method!
So, try the latest version of Notepad++ released today, you can download it at the project’s homepage. Please come back and report the results of your tests, they will be very useful for the community.
If the issue is not resolved, @pnedev and you should talk about how your program exactly accesses files to be able to find the culprit.
I’m sorry, I was wrong. The fix I mentioned above has not been merged to the code base of Notepad++, it’s still an open pull request at the GitHub repository of Notepad++.
Is your new posting significantly different from the batch you posted on 2019 Aug 5-6 ?
@dinkumoil FWIW, the basic process my program goes through is:
- Use GetPrivateProfileString() many times to read the INI file.
- Use WritePrivateProfileString() many times to update the INI file with changes the user made.
- Within a second or two, the main loop detects the file change and re-reads the file using the same “loadini” function it used at startup.
That obviously leaves out everything else my program does, but the system private profile functions are the only method my program uses to read the INI file. Even more specifically, I use GetPrivateProfileSectionNames, GetPrivateProfileSection, GetPrivateProfileString, WritePrivateProfileSection (to delete a section) and WritePrivateProfileString. That’s it.
The only thing I can imagine is that there may be a timing issue between when my program writes changes then immediately reads them back and when I activate Notepad++ and it detects the change (or something else?) Maybe Windows keeps the file locked for a short time after the last WritePrivateProfileString call (in case the program is going to call it again) and I sometimes manage to activate Notepad++ during the window?
Just a shot in the dark, but it is all I’ve got right now. If I can be of any help or run any tests, please let me know what I can do.
Sorry, I just found my previous question about this same issue at erasing all or part of file back in August. I don’t know how (or have the ability) to combine these, but feel free.
There are couple differences (or ‘new things’) in this report, though: I had not previously seen the message from NPP offering to run as Admin in conjunction with this and this time I was testing a component that wrote to the file instead of only using one that read from the file.
I just thought of one more thing that may or may not be of interest/use:
My program has a thread that watches specific files for changes using FindFirstChangeNotification()/FindNextChangeNotification(). If a change to one of the files is detected, the thread posts a message to the main loop and the main loop re-reads the file when it receives the message. This keeps all of the actual file reading (and writing, if the users uses the config dialog) in the same thread.
About your older thread, that from August:
What might be happening is that when Notepad++ is saving the file it first opens it with
fopen()which erases the file.
This is perhaps immediately detected by your program that ‘locks’ the file to re-read it and during that time Notepad++ tries to write the changed contents. This fails as your program has locked the file. Notepad++ fails writing the file and exits leaving the file empty.
This is just a guess of course but if this is the case then the fix I made should prevent this from happening.
But as @dinkumoil mentioned my fix is still not accepted and merged into Notepad++ so currently your issue will still be there.
@pnedev That is a very believable scenario. I wonder if adding a short delay before I notify my main loop of the file change would help at all. Looking forward to your fix being incorporated. Thanks!
I wonder if adding a short delay before I notify my main loop …
It is worth trying.
Please write back if that helps (if you test it).
@pnedev I added a 5 second delay between detecting the file change and notifying the main loop. If the file is detected again during the delay, the delay is reset to the full 5 seconds. There is probably still a timing window when the file is being saved just as the notification is sent to/processed by the main loop, but it seems small and this has been working for the short while that I have been testing it. I’m not thrilled about the lag between saving a change and seeing that my program is using the new setting, but I will need to live with it for now. At least my time delay is a setting itself, so I can easily turn it off later, when it is time to see of NPP is fixed. (smile) Thanks again for your thoughts and, hopefully, thanks for your fix – whenever it makes it in!
@pnedev I have noticed that I get TWO apparently identical notifications about the file change event when Notepad++ saves the file, but things like the original Notepad and KeditW32 save the same file to the same folder, my program receives only ONE event notification about the file change.
(Strangely, VS2019 generated 11 events, 3 of which referenced the file I changed and the others all appear to be random temp file/dir names.)
I have tried this using the FindFirstChangeNotification / FindNextChangeNotification functions and re-implemented this morning to try using ReadDirectoryChangesW instead. Both generate the same number of events when Notepad++ saves a file, but the read version lets me know for certain that the events are specifically about the file and not the directory itself or a different file.
I don’t know if this helps or is of any use. If you (or anyone, really) wants to create a test app that uses the monitor functions and then reads an ini file, I can provide my monitoring module (it will need some clean up to eliminate calls to the remainder of the application, but I think it is mostly self-contained.) Just tell me where/how to post it.
Unless I find something truly new and amazing about this, I won’t pester the community about it any more. Thanks for all of your assistance and information, it really helped!
If you’d like you can try my AppVeyor PR Notepad++ exe build from here:
This is version 7.7.1 + my fix so you’ll need Notepad++ 7.7.1 (either install it or use the portable) but replace the exe with the one from the link (just get the correct build - x64 or x32).
You can then check how many notifications you are getting with it and also try removing your delay and see how it behaves.
@pnedev With your 32 bit version I am still seeing two events when NPP saves the file and when I switched to a zero delay before reloading the content [via GetPrivateProfileString()], it only took a couple of tries before I started to see this message box from NPP when I clicked save:
The file cannot be saved and it may be protected.
Do you want to launch Notepad++ in Administrator mode?
When that message box is visible, my program has loaded all default settings (used when an empty or missing INI file is detected). I was able to click NO and then ask NPP to save again, which has worked – so far. This does not happen every time, but it did happen a few times in only a couple minutes testing.
(Also, just FYI: the tab title when I downloaded your file says notepad-plus-plus 7.6.35 - AppVeyor, by the way, even though the About shows 7.7.1)
Thanks for trying.
Are you sure it was written notepad-plus-plus 7.6.35 - AppVeyor and not notepad-plus-plus 7.6.53 - AppVeyor?
This is AppVeyor build number it is not related to Notepad++ version.
And what would happen if you say Yes to switching to Admin mode? (If you try it please backup your files so you can recover if those get zeroed.)
@pnedev I’m sure the .35 is a typo, sorry. It was close enough to NPP’s version that I thought it might have been overlooked when the NPP version changed. Sorry.
When I click YES for Admin mode, I ended up with an Admin NPP running and showing an EMPTY file. Behind the Admin copy, the original was still running, too, and it was now showing this new message box:
This file has been modified by another program.
Do you want to reload it and lose the changes made in Notepad++?
When I clicked Yes on this message, that NPP also showed a completely empty copy of the INI file.
So, I am not sure why NPP needs to modify the file (or file’s metadata?) twice, but with no delay after the OS tells it about the change, my program is able to start reading before the second modify and getting an empty file – and often causing NPP to leave the empty file behind.
This is probably no help at all, but here is the sequence of events my program logs when VS2019 saves the file using a very safe method:
ADDED : cetwiqja.43f~ MODIFIED : cetwiqja.43f~ MODIFIED : cetwiqja.43f~ ADDED : ev11.ini~RFd859b.TMP REMOVED : ev11.ini~RFd859b.TMP RENAMED(old): ev11.ini RENAMED(new): ev11.ini~RFd859b.TMP RENAMED(old): cetwiqja.43f~ RENAMED(new): ev11.ini MODIFIED : ev11.ini REMOVED : ev11.ini~RFd859b.TMP
While there are many more events, there is only one MODIFY of the INI file and that is due to a rename, so the file is neither open nor locked when the system notifies other programs.
Let me know if there are any more tests I can perform for you. I am happy to help. Thanks for your interest in this, too!
I’m sure the .35 is a typo
If the string was notepad-plus-plus 7.6.53 - AppVeyor then I suspect you have gotten my Notepad++ exe build without the fix.
Are you sure you have downloaded this 32-bit exe:
https://ci.appveyor.com/api/buildjobs/g720d29abjg08fnx/artifacts/Notepad%2B%2B.Win32.Unicode Release.exe ?
So just to clarify:
You are getting the same behavior as with the original Notepad++ 7.7.1 exe?
And when you say Yes to Admin mode is the file with zero size on the disk as well?
Thank you for testing once again.
@pnedev sorry about the mix-up, I had difficulty finding the correct file from the link you provided. The file name was the same, but the direct-linked file I just downloaded was slightly larger and only generates ONE modify event when the file is saved.
I have tried the steps that were reliably generating a problem quite a few times using the new file and I have not encountered the problem again. So now that I actually have your fix, I think it works.
(And yes, in the other build when I said Yes to Admin mode, the file was zero length according to File Explorer.)
Thanks again and I hope the “NPP powers that be” accept your change for inclusion in the main project soon!