Attempt renaming multiple times on safe file save, and make the behavior optional. Fixes #14339.
This commit is contained in:
parent
d486cae701
commit
e56b3439a5
2 changed files with 26 additions and 15 deletions
|
@ -31,6 +31,7 @@
|
|||
#ifdef WINDOWS_ENABLED
|
||||
|
||||
#include "file_access_windows.h"
|
||||
#include "os/os.h"
|
||||
#include "shlwapi.h"
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -115,25 +116,35 @@ void FileAccessWindows::close() {
|
|||
//_wunlink(save_path.c_str()); //unlink if exists
|
||||
//int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());
|
||||
|
||||
bool rename_error;
|
||||
bool rename_error = true;
|
||||
int attempts = 4;
|
||||
while (rename_error && attempts) {
|
||||
// This workaround of trying multiple times is added to deal with paranoid Windows
|
||||
// antiviruses that love reading just written files even if they are not executable, thus
|
||||
// locking the file and preventing renaming from happening.
|
||||
|
||||
#ifdef UWP_ENABLED
|
||||
// UWP has no PathFileExists, so we check attributes instead
|
||||
DWORD fileAttr;
|
||||
// UWP has no PathFileExists, so we check attributes instead
|
||||
DWORD fileAttr;
|
||||
|
||||
fileAttr = GetFileAttributesW(save_path.c_str());
|
||||
if (INVALID_FILE_ATTRIBUTES == fileAttr) {
|
||||
fileAttr = GetFileAttributesW(save_path.c_str());
|
||||
if (INVALID_FILE_ATTRIBUTES == fileAttr) {
|
||||
#else
|
||||
if (!PathFileExistsW(save_path.c_str())) {
|
||||
if (!PathFileExistsW(save_path.c_str())) {
|
||||
#endif
|
||||
//creating new file
|
||||
rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0;
|
||||
} else {
|
||||
//atomic replace for existing file
|
||||
rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL);
|
||||
}
|
||||
if (rename_error && close_fail_notify) {
|
||||
close_fail_notify(save_path);
|
||||
//creating new file
|
||||
rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0;
|
||||
} else {
|
||||
//atomic replace for existing file
|
||||
rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL);
|
||||
}
|
||||
if (rename_error && close_fail_notify) {
|
||||
close_fail_notify(save_path);
|
||||
}
|
||||
if (rename_error) {
|
||||
attempts--;
|
||||
OS::get_singleton()->delay_usec(1000000); //wait 100msec and try again
|
||||
}
|
||||
}
|
||||
|
||||
save_path = "";
|
||||
|
|
|
@ -4749,7 +4749,7 @@ EditorNode::EditorNode() {
|
|||
scene_distraction = false;
|
||||
script_distraction = false;
|
||||
|
||||
FileAccess::set_backup_save(true);
|
||||
FileAccess::set_backup_save(EDITOR_DEF("filesystem/on_save/safe_save_on_backup_then_rename", true));
|
||||
|
||||
TranslationServer::get_singleton()->set_enabled(false);
|
||||
// load settings
|
||||
|
|
Loading…
Reference in a new issue