In my app, I move one file over top of another. You know, write out a file in /tmp then, when its all written, use the new file to replace an existing one.
But on Windows, I found that a few users have reported this is not working, I do this -
...
My own Win10 system does not exhibit this problem but others do. Can anyone suggest whats happening here please ?
Davo
"if not DeleteFileUTF8(FileName)"? On Windows? Windows is an UTF16 OS.
* that they can, manually, remove the file themselves.
<snip>
Can anyone suggest whats happening here please ?
In trunk it simply calls SysUtils.DeleteFile() (which does the W-API call).Well then. That's what I mean. Nice to see that in trunk, because as you state this has not always been the case. :D
Even in older versions it called DeleteFileW. Here (https://svn.freepascal.org/cgi-bin/viewvc.cgi/branches/fixes_1_0/components/lazutils/winfileutil.inc?view=markup&revision=38249&root=lazarus#l532) is the code from Lazarus 1.0. If you follow the initialization for the function variable DeleteFile_ you'll notice that it's initialized to a function that calls DeleteFileW except on older Windows versions (older than Windows 2000).In trunk it simply calls SysUtils.DeleteFile() (which does the W-API call).Well then. That's what I mean. Nice to see that in trunk, because as you state this has not always been the case. :D
Even in older versions it called DeleteFileW.
OK, I have finally sorted this out, superficially at least.
While I cannot reproduce the problem myself, a cooperative end user has been running tests and returning log file to me.
Whats happening I believe is that when you call DeleteFileUTF8() in windows, the file is (almost always?) deleted but sometimes the function returns false. My guess is that its not having its return value set reliably. There is a path through the function that allows Result to be random. As the function very rarely fails, few of us check its return value and it has gone unnoticed.
My diagnose is based on calling DeleteFileUTF8() and if it returns false, call FileExists() to really see if its gone. If FileExits() retuns false, allow the programe to proceed, hopefully normally. So far, his tests indicatate that is the case.
I will, in the near future, try and step though the Windows code (bit out of my comfort zone) and will follow up on what I find.
For the record, this end user also has Vera-Crypt running on his windows box and also uses PortableApps.com. I don't think there is any connection but worth noting.....
Davo
The problem really does appear to be that DeleteFileUTF8() can return false even when it correctly deleted the file.So at the end this could be fixed with just additional check for FileExists()?
Hello!
What says the OS Error Msg??
Before that I would insert:
Io := IoResult;
and then write it with DebugLn
....
Here's a snippet what I use to reliably delete files in Windows 10...
....
One, the FileExists() check is unnecessary, as DeleteFileW() will do the same check and set GetLastError() accordingly.
.....
Just for the record, several variations that I sent the end user apparently received no error message from DeleteFile() and DeleteFileUTF8() but a subsequent call to FileExists() revealed that the file was, in fact still present.
And, on one occasion, I saw a log that indicated, perhaps, the file was deleted but DeleteFile() said it failed !