mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-10 07:40:03 -06:00
cmSystemTools: Teach RenameFile to disable Windows Search Indexing
Create RAII class SaveRestoreFileAttributes to manage Windows Search Indexing. Turn it off temporarily while renaming a directory. Issue: #19580
This commit is contained in:
@@ -751,6 +751,57 @@ std::string cmSystemTools::FileExistsInParentDirectories(
|
||||
#ifdef _WIN32
|
||||
namespace {
|
||||
|
||||
/* Helper class to save and restore the specified file (or directory)
|
||||
attribute bits. Instantiate this class as an automatic variable on the
|
||||
stack. Its constructor saves a copy of the file attributes, and then its
|
||||
destructor restores the original attribute settings. */
|
||||
class SaveRestoreFileAttributes
|
||||
{
|
||||
public:
|
||||
SaveRestoreFileAttributes(std::wstring const& path,
|
||||
uint32_t file_attrs_to_set);
|
||||
~SaveRestoreFileAttributes();
|
||||
|
||||
SaveRestoreFileAttributes(SaveRestoreFileAttributes const&) = delete;
|
||||
SaveRestoreFileAttributes& operator=(SaveRestoreFileAttributes const&) =
|
||||
delete;
|
||||
|
||||
void SetPath(std::wstring const& path) { path_ = path; }
|
||||
|
||||
private:
|
||||
std::wstring path_;
|
||||
uint32_t original_attr_bits_;
|
||||
};
|
||||
|
||||
SaveRestoreFileAttributes::SaveRestoreFileAttributes(
|
||||
std::wstring const& path, uint32_t file_attrs_to_set)
|
||||
: path_(path)
|
||||
, original_attr_bits_(0)
|
||||
{
|
||||
// Set the specified attributes for the source file/directory.
|
||||
original_attr_bits_ = GetFileAttributesW(path_.c_str());
|
||||
if ((INVALID_FILE_ATTRIBUTES != original_attr_bits_) &&
|
||||
((file_attrs_to_set & original_attr_bits_) != file_attrs_to_set)) {
|
||||
SetFileAttributesW(path_.c_str(), original_attr_bits_ | file_attrs_to_set);
|
||||
}
|
||||
}
|
||||
|
||||
// We set attribute bits. Now we need to restore their original state.
|
||||
SaveRestoreFileAttributes::~SaveRestoreFileAttributes()
|
||||
{
|
||||
DWORD last_error = GetLastError();
|
||||
// Verify or restore the original attributes.
|
||||
const DWORD source_attr_bits = GetFileAttributesW(path_.c_str());
|
||||
if (INVALID_FILE_ATTRIBUTES != source_attr_bits) {
|
||||
if (original_attr_bits_ != source_attr_bits) {
|
||||
// The file still exists, and its attributes aren't our saved values.
|
||||
// Time to restore them.
|
||||
SetFileAttributesW(path_.c_str(), original_attr_bits_);
|
||||
}
|
||||
}
|
||||
SetLastError(last_error);
|
||||
}
|
||||
|
||||
struct WindowsFileRetryInit
|
||||
{
|
||||
cmSystemTools::WindowsFileRetry Retry;
|
||||
@@ -924,6 +975,12 @@ bool cmSystemTools::RenameFile(const std::string& oldname,
|
||||
Try multiple times since we may be racing against another process
|
||||
creating/opening the destination file just before our MoveFileEx. */
|
||||
WindowsFileRetry retry = GetWindowsRetry(oldname_wstr);
|
||||
|
||||
// Use RAII to set the attribute bit blocking Microsoft Search Indexing,
|
||||
// and restore the previous value upon return.
|
||||
SaveRestoreFileAttributes save_restore_file_attributes(
|
||||
oldname_wstr, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
||||
|
||||
DWORD move_last_error = 0;
|
||||
while (!cmMoveFile(oldname_wstr, newname_wstr) && --retry.Count) {
|
||||
move_last_error = GetLastError();
|
||||
@@ -961,6 +1018,8 @@ bool cmSystemTools::RenameFile(const std::string& oldname,
|
||||
// If we were successful, then there was no error.
|
||||
if (retry.Count > 0) {
|
||||
move_last_error = 0;
|
||||
// Restore the attributes on the new name.
|
||||
save_restore_file_attributes.SetPath(newname_wstr);
|
||||
}
|
||||
SetLastError(move_last_error);
|
||||
return retry.Count > 0;
|
||||
|
||||
Reference in New Issue
Block a user