首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 修改資料夾時間屬性:以 CreateFile 開啟目錄搭配 SetFileTime

     編輯:VC 教學

前言

Windows 沒有直接提供修改資料夾(目錄)時間的介面,但 CreateFile 設定 FILE_FLAG_BACKUP_SEMANTICS 旗標後,即可取得目錄的控制代碼,進而使用原本針對檔案的 GetFileTime / SetFileTime 讀寫建立、存取、修改時間。此技巧常用於完整備份還原系統,確保根目錄與子目錄時間戳一致。

核心技巧:以檔案方式開啟目錄

HANDLE hDir = CreateFile(
    dirPath,                          // 目錄完整路徑
    GENERIC_READ | GENERIC_WRITE,     // 讀寫權限
    FILE_SHARE_READ | FILE_SHARE_DELETE,
    NULL,
    OPEN_EXISTING,                    // 必須為 OPEN_EXISTING
    FILE_FLAG_BACKUP_SEMANTICS,       // 關鍵旗標:允許開啟目錄
    NULL);
if (hDir == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError(); // 處理錯誤
    return FALSE;
}

取得目錄時間(轉為 SYSTEMTIME 方便操作)

BOOL GetDirTime(LPCTSTR dirPath, SYSTEMTIME& stLocal)
{
    HANDLE hDir = CreateFile(dirPath, GENERIC_READ,
                             FILE_SHARE_READ|FILE_SHARE_DELETE,
                             NULL, OPEN_EXISTING,
                             FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (hDir == INVALID_HANDLE_VALUE) return FALSE;

    FILETIME ftCreate, ftAccess, ftWrite;
    BOOL ok = GetFileTime(hDir, &ftCreate, &ftAccess, &ftWrite);
    CloseHandle(hDir);
    if (!ok) return FALSE;

    // UTC → 本地時間 → SYSTEMTIME
    FILETIME ftLocal;
    FileTimeToLocalFileTime(&ftWrite, &ftLocal);
    FileTimeToSystemTime(&ftLocal, &stLocal);
    return TRUE;
}

設定目錄時間(由 SYSTEMTIME 轉回 FILETIME)

BOOL SetDirTime(LPCTSTR dirPath, const SYSTEMTIME& stLocal)
{
    HANDLE hDir = CreateFile(dirPath, GENERIC_WRITE,
                             FILE_SHARE_READ|FILE_SHARE_DELETE,
                             NULL, OPEN_EXISTING,
                             FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (hDir == INVALID_HANDLE_VALUE) return FALSE;

    FILETIME ftCreate, ftAccess, ftWrite;
    SystemTimeToFileTime(&stLocal, &ftCreate);
    SystemTimeToFileTime(&stLocal, &ftAccess);
    SystemTimeToFileTime(&stLocal, &ftWrite);

    BOOL ok = SetFileTime(hDir, &ftCreate, &ftAccess, &ftWrite);
    CloseHandle(hDir);
    return ok;
}

使用範例

SYSTEMTIME st;
if (GetDirTime(_T("D:\\BackupRoot"), st)) {
    // 視需求修改 st,或直接保持原樣
    // st.wYear = 2023; st.wMonth = 1; st.wDay = 1; ...
    SetDirTime(_T("D:\\BackupRoot"), st);
}

注意事項

  • 需管理員權限:修改非使用者自有目錄時間需提升權限。
  • 時間精度:NTFS 解析度 100 奈秒;FAT32 僅 2 秒,設定後可能被截斷。
  • 遞迴處理:完整備份需遞迴走訪所有子目錄套用相同邏輯。
  • 備份軟體相容:Windows 備份工具已內建此機制,自製工具才需手動實作。

延伸:同時修改檔案與目錄

同樣的 GetFileTime/SetFileTime 適用於檔案(不需 FILE_FLAG_BACKUP_SEMANTICS)。可撰寫統一介面 SetItemTime(path, st, isDirectory) 簡化呼叫端。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved