UI/updater: Move in-use files away before writing
On a modern Windows OS, you can rename an in-use file despite not being able to write to it. With the introduction of the virtual camera, it is now quite common that users will have in-use files when updating. This commit renames in-use files, allowing the new version to be installed. Upon a reboot, the previously in-use file will be deleted.
This commit is contained in:
parent
c0d7602b64
commit
9201390a46
@ -786,6 +786,41 @@ static void UpdateWithPatchIfAvailable(const char *name, const char *hash,
|
||||
}
|
||||
}
|
||||
|
||||
static bool MoveInUseFileAway(update_t &file)
|
||||
{
|
||||
_TCHAR deleteMeName[MAX_PATH];
|
||||
_TCHAR randomStr[MAX_PATH];
|
||||
|
||||
BYTE junk[40];
|
||||
BYTE hash[BLAKE2_HASH_LENGTH];
|
||||
|
||||
CryptGenRandom(hProvider, sizeof(junk), junk);
|
||||
blake2b(hash, sizeof(hash), junk, sizeof(junk), NULL, 0);
|
||||
HashToString(hash, randomStr);
|
||||
randomStr[8] = 0;
|
||||
|
||||
StringCbCopy(deleteMeName, sizeof(deleteMeName),
|
||||
file.outputPath.c_str());
|
||||
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), L".");
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), randomStr);
|
||||
StringCbCat(deleteMeName, sizeof(deleteMeName), L".deleteme");
|
||||
|
||||
if (MoveFile(file.outputPath.c_str(), deleteMeName)) {
|
||||
|
||||
if (MyCopyFile(deleteMeName, file.outputPath.c_str())) {
|
||||
MoveFileEx(deleteMeName, NULL,
|
||||
MOVEFILE_DELAY_UNTIL_REBOOT);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
MoveFile(deleteMeName, file.outputPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool UpdateFile(update_t &file)
|
||||
{
|
||||
wchar_t oldFileRenamedPath[MAX_PATH];
|
||||
@ -838,6 +873,9 @@ static bool UpdateFile(update_t &file)
|
||||
|
||||
int error_code;
|
||||
bool installed_ok;
|
||||
bool already_tried_to_move = false;
|
||||
|
||||
retryAfterMovingFile:
|
||||
|
||||
if (file.patchable) {
|
||||
error_code = ApplyPatch(file.tempPath.c_str(),
|
||||
@ -877,15 +915,23 @@ static bool UpdateFile(update_t &file)
|
||||
int is_sharing_violation =
|
||||
(error_code == ERROR_SHARING_VIOLATION);
|
||||
|
||||
if (is_sharing_violation)
|
||||
if (is_sharing_violation) {
|
||||
if (!already_tried_to_move) {
|
||||
already_tried_to_move = true;
|
||||
|
||||
if (MoveInUseFileAway(file))
|
||||
goto retryAfterMovingFile;
|
||||
}
|
||||
|
||||
Status(L"Update failed: %s is still in use. "
|
||||
L"Close all "
|
||||
L"programs and try again.",
|
||||
curFileName);
|
||||
else
|
||||
} else {
|
||||
Status(L"Update failed: Couldn't update %s "
|
||||
L"(error %d)",
|
||||
curFileName, GetLastError());
|
||||
}
|
||||
|
||||
file.state = STATE_INSTALL_FAILED;
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user