使用 SHFileOperation 按日期删除文件和文件夹

发布于 2024-12-10 09:13:54 字数 1375 浏览 0 评论 0原文

我正在尝试编写一个程序,该程序将使用 Windows API 删除根据日期匹配特定命名模式(通配符)的一组文件/文件夹,

...

    SHFILEOPSTRUCT shFileOpStruct = {
            .hwnd   = NULL,
            .wFunc  = processByDate->op,
            .pTo    = NULL,
            .fFlags = FOF_NOCONFIRMATION | FOF_SILENT
    };

    buildReferenceDate( &refTime, processByDate->nDays );
    hFind = FindFirstFile( processByDate->srcFileName, &findFileData );
    errorCode = GetLastError();

    while ( errorCode == ERROR_SUCCESS ) {
        LONG res = CompareFileTime( &refTime, &findFileData.ftCreationTime );

        if ( (processByDate->nDays ^ res) > 0 ) {
            sprintf( strrchr(processByDate->srcFileName, '\\') + 1, "%s%c",
                                             findFileData.cFileName, '\0');
            shFileOpStruct.pFrom = processByDate->srcFileName;
            fprintf( stdout, "\n%s\n", shFileOpStruct.pFrom);
            fprintf( stdout, "\n0x%x\n", SHFileOperation( &shFileOpStruct ));
        }
        FindNextFile( hFind, &findFileData );
        errorCode = GetLastError();
    }

    if ( errorCode != ERROR_NO_MORE_FILES )
        displayError ( stdout, errorCode );

...    

仅删除第一个匹配的文件,因为 FindNextFile 以“The句柄无效。”显然 SHFileOperation 以某种方式使文件句柄无效(或者至少我认为如此)。我能想到的唯一解决方案就是保存匹配的文件/文件夹的名称并一一删除。还有其他更简单的解决方案吗?

谢谢

I'm trying to write a program that will delete a set of files/folders that are matching a specific naming pattern (wild cards) based on their dates using the windows API

...

    SHFILEOPSTRUCT shFileOpStruct = {
            .hwnd   = NULL,
            .wFunc  = processByDate->op,
            .pTo    = NULL,
            .fFlags = FOF_NOCONFIRMATION | FOF_SILENT
    };

    buildReferenceDate( &refTime, processByDate->nDays );
    hFind = FindFirstFile( processByDate->srcFileName, &findFileData );
    errorCode = GetLastError();

    while ( errorCode == ERROR_SUCCESS ) {
        LONG res = CompareFileTime( &refTime, &findFileData.ftCreationTime );

        if ( (processByDate->nDays ^ res) > 0 ) {
            sprintf( strrchr(processByDate->srcFileName, '\\') + 1, "%s%c",
                                             findFileData.cFileName, '\0');
            shFileOpStruct.pFrom = processByDate->srcFileName;
            fprintf( stdout, "\n%s\n", shFileOpStruct.pFrom);
            fprintf( stdout, "\n0x%x\n", SHFileOperation( &shFileOpStruct ));
        }
        FindNextFile( hFind, &findFileData );
        errorCode = GetLastError();
    }

    if ( errorCode != ERROR_NO_MORE_FILES )
        displayError ( stdout, errorCode );

...    

Only the first matching file is deleted, because FindNextFile terminates with "The handle is invalid." apparently SHFileOperation somehow invalidates the file handle (or at least so I suppose). The only solution I can think of is to save the name of the matching files/folders and delete them one by one. Is there any other simpler solution?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时常饿 2024-12-17 09:13:54
    FindNextFile( hFind, &findFileData );
    errorCode = GetLastError();

那是错误的。 当 FindNextFile() 返回 FALSE 时才调用 GetLastError()。使固定:

    if (!FindNextFile( hFind, &findFileData ) {
        errorCode = GetLastError();
    }
    FindNextFile( hFind, &findFileData );
    errorCode = GetLastError();

That's wrong. Only call GetLastError() when you get a FALSE return from FindNextFile(). Fix:

    if (!FindNextFile( hFind, &findFileData ) {
        errorCode = GetLastError();
    }
听,心雨的声音 2024-12-17 09:13:54

当函数成功时,不会设置线程的最后一个错误代码。您必须检查 FindNextFile 的返回值,而不是调用 GetLastError

如果函数成功,则返回值非零,并且 lpFindFileData 参数包含有关找到的下一个文件或目录的信息。

如果函数失败,返回值为零,并且 lpFindFileData 的内容不确定。

FindNextFile 函数

循环应如下所示:

HANDLE handle(FindFirstFile(...));
if (handle != INVALID_HANDLE_VALUE)
{
    do
    {
        // filter files here
    }
    while (FindNextFile(handle, ...));
    FindClose(handle);
}

The thread's last error code is not set when a function succeeds. Instead of calling GetLastError, you have to check the return value of FindNextFile.

If the function succeeds, the return value is nonzero and the lpFindFileData parameter contains information about the next file or directory found.

If the function fails, the return value is zero and the contents of lpFindFileData are indeterminate.

FindNextFile function

The loop should look like this:

HANDLE handle(FindFirstFile(...));
if (handle != INVALID_HANDLE_VALUE)
{
    do
    {
        // filter files here
    }
    while (FindNextFile(handle, ...));
    FindClose(handle);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文