RemoveDirectory失败 错误代码145

今天写一个删除目录的程序(目录下包含子目录),遇到点问题,代码如下:

/////////////////////////////////////////
//    删除目录及子目录下所有文件           //
/////////////////////////////////////////

BOOL DeleteAllFileFromDirectoryW(LPCWSTR lpPath)
{
    HANDLE hFind;
    WCHAR wzDeletePath[MAX_PATH] = { 0 };
    WIN32_FIND_DATA findFileData;
    BOOL bRet = FALSE;

    ZeroMemory(&findFileData, sizeof(WIN32_FIND_DATA));

    //切换到要删除的路径
    //
    _wchdir(lpPath);

    //检查路径是否以“\”结尾
    //
    wcscpy_s(wzDeletePath, MAX_PATH, lpPath);
    if (L‘\\‘ != wzDeletePath[wcslen(wzDeletePath) - 1])
    {
        wcscat_s(wzDeletePath, MAX_PATH, L"\\");
    }

    //在路径后面添加通配符“*.*”
    //
    wcscat_s(wzDeletePath, MAX_PATH, L"*.*");

    //寻找第一个文件
    //
    hFind = FindFirstFileW(wzDeletePath, &findFileData);
    if (INVALID_HANDLE_VALUE == hFind)
    {
        //错误提示,路径不存在
        return bRet;
    }

    //开始遍历
    //
    do
    {
        wcscpy_s(wzDeletePath, MAX_PATH, lpPath);
        wcscat_s(wzDeletePath, MAX_PATH, L"\\");
        wcscat_s(wzDeletePath, MAX_PATH, findFileData.cFileName);

        //如果是目录,过滤掉“.”和“..”目录,递归遍历
        //
        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if ((0 == wcscmp(L".", findFileData.cFileName)) || (0 == wcscmp(L"..", findFileData.cFileName)))
            {
                continue;
            }

            //递归遍历
            DeleteAllFileFromDirectoryW(wzDeletePath);
        }
        //文件,直接删除
        //
        else
        {
            if (!DeleteFileW(wzDeletePath))
            {
                //错误输出,删除文件失败
                continue;
            }
        }

    } while (FindNextFileW(hFind, &findFileData));

    //文件夹遍历完毕后切换到父文件夹,删除此文件夹
    //
    _wchdir(L"..");
    if (!RemoveDirectoryW(lpPath))
    {
        //错误输出,删除文件夹失败
        return bRet;
    }

    bRet = TRUE;
    return bRet;
}

程序运行后发现总有一些文件夹没删除,当时特别疑惑,就在“RemoveDirectoryW”处打了断点,用GetCurrentDirectoryW函数获取当前路径,用GetLastError观测错误代码

最后发现在删除一些文件夹失败时,错误代码为145-目录不是空的。此时将程序终止,去查看此目录是否为空,发现确实是空的。奇怪了,每次删除目录前是先切换到父目录呀,而且确实目录下没有文件了呀,郁闷。。

又把程序仔仔细细的看了几遍,去找了文件遍历的例子看了看,忽然发现自己犯了一个二笔的错误,遍历文件后忘记了这句:

 FindClose(hFind);

真是粗心啊,文件搜索的句柄没有关闭导致文件夹无法删除,但是为什么其它文件夹就能删除呢?这个问题就不知道了,反正问题解决了,以后写程序要细心啊,不能犯这种低级错误了。

把正确的代码放到下面,如果你需要参考,别复制错了^_^

/////////////////////////////////////////
//     删除目录及子目录下所有文件         //
/////////////////////////////////////////

BOOL DeleteAllFileFromDirectoryW(LPCWSTR lpPath)
{
    HANDLE hFind;
    WCHAR wzDeletePath[MAX_PATH] = { 0 };
    WIN32_FIND_DATA findFileData;
    BOOL bRet = FALSE;

    ZeroMemory(&findFileData, sizeof(WIN32_FIND_DATA));

    //切换到要删除的路径
    //
    _wchdir(lpPath);

    //检查路径是否以“\”结尾
    //
    wcscpy_s(wzDeletePath, MAX_PATH, lpPath);
    if (L‘\\‘ != wzDeletePath[wcslen(wzDeletePath) - 1])
    {
        wcscat_s(wzDeletePath, MAX_PATH, L"\\");
    }

    //在路径后面添加通配符“*.*”
    //
    wcscat_s(wzDeletePath, MAX_PATH, L"*.*");

    //寻找第一个文件
    //
    hFind = FindFirstFileW(wzDeletePath, &findFileData);
    if (INVALID_HANDLE_VALUE == hFind)
    {
        //错误提示,路径不存在
        return bRet;
    }

    //开始遍历
    //
    do
    {
        wcscpy_s(wzDeletePath, MAX_PATH, lpPath);
        wcscat_s(wzDeletePath, MAX_PATH, L"\\");
        wcscat_s(wzDeletePath, MAX_PATH, findFileData.cFileName);

        //如果是目录,过滤掉“.”和“..”目录,递归遍历
        //
        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if ((0 == wcscmp(L".", findFileData.cFileName)) || (0 == wcscmp(L"..", findFileData.cFileName)))
            {
                continue;
            }

            //递归遍历
            DeleteAllFileFromDirectoryW(wzDeletePath);
        }
        //文件,直接删除
        //
        else
        {
            if (!DeleteFileW(wzDeletePath))
            {
                //错误输出,删除文件失败
                continue;
            }
        }

    } while (FindNextFileW(hFind, &findFileData));

    FindClose(hFind);

    //文件夹遍历完毕后切换到父文件夹,删除此文件夹
    //
    _wchdir(L"..");
    if (!RemoveDirectoryW(lpPath))
    {
        //错误输出,删除文件夹失败
        return bRet;
    }

    bRet = TRUE;
    return bRet;
}
时间: 2024-07-29 23:47:36

RemoveDirectory失败 错误代码145的相关文章

Chrome 安装失败 错误代码 0X80070057

错误现象: Chrome 浏览器崩溃,点击任何页面均显示崩溃,而且无法卸载.将原文件夹删除,并且删除全部注册表信息之后,重新下载安装包,点击后,显示无法安装,错误代码0X80070057. 解决办法, 当双击安装包,显示错误无法安装的时候,不要关闭界面.进入文件夹: C:\Program Files (x86)\GUMBE4F.tmp 不同电脑文件夹的二级名称可能不一样,注意后缀 dot tmp是安装过程中产生的临时文件夹,进入后发现有一个exe文件夹被重新命名,出现了双后缀,把后面的字符删掉保

NBU虚拟机备份失败-错误代码156

参考Symantec知识库文档HOWTO70878 http://www.symantec.com/business/support/index?page=content&id=HOWTO70878 虚拟机显示名称(DisplayName):在VMware vCenter列表中的显示名 虚拟机磁盘文件(Virtual Machine Disk Name):在DATASTORE中的虚拟机磁盘文件名称 虚拟机文件夹(Virtual Machine Folder):在DATASTORE中的虚拟机文件夹

糟糕 安装失败 错误代码0xa0430721 解决方案

安装失败可能是因为删除文件时没有删除干净. 本人试了一种方法可行. 步骤: (1)新创建一个文本文档. (2)将以下内容复制到文档里头. Windows Registry Editor Version 5.00 ; WARNING, this file will remove Google Chrome registry entries ; from your Windows Registry. Consider backing up your registry before ; using t

WSUS客户端更新失败错误代码:80072EE2

问题描述:客户端使用WSUS服务器更新补丁报错 80072EE2 服务器无报告状态. 原因分析: 应用程序池的专用内存限制 (KB) 可能设置为默认值 1843200 KB错误日志:ID 1309解决方案: 打开IIS管理控制台---应用程序池----WSusPool池----高级设置-修改专用内存限制-重启服务器. 计算机更新正常: 原文地址:http://blog.51cto.com/10981246/2092883

安装docker后启动失败

问题: 安装完成Docker后,打开Docker Quickstart Terminal出现  Error:creating VirtualBox 失败. 然后直接打开Oracle VM VirtualBox,出现错误: 获取 VirtualBox COM 对象失败. 错误代码如下;       Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, CLSID_VirtualBox w/ IUnknown works.       PSDi

ensp模拟器常见问题解决方法

以下是我在使用ensp中遇到过的问题,大家可以一步步排查. 长时间输出################或者提示40错误 检查PC上面是否成功安装virtualbox网卡 查看virtualbox网卡IP地址是否为192.168.56.1 勾选 "VirtualBox NDIS6 Bridged Networking Driver"协议. 防火墙设置 检查杀毒软件,看看是不是杀毒软件阻止了模拟设备之间的通信 检查Virtualbox安装目录是否存在中文,如果有请修改成英文 检查电脑BIO

第15章 在应用程序中使用虚拟内存(2)

15.6 改变保护属性 (1)VritualProtect函数 参数 描述 PVOID pvAddress 指向要修改属性的内存基地址 SIZE_T dwSize 区域的大小,以字节为单位 DWORD flNewProtect PAGE_*(除PAGE_WRITECOPY.PAGE_EXCUTE_WRITECOPY外) PDWORD pflOldProtect 返回原来的保护属性,有时虽然不需要返回这个信息,但必须传入一个有效的pflOldProtect参数 (2)注意点 ①保护属性是与整个物理

用post来进行Soap请求

最近调了一个Soap请求C# webservice的项目.网上坑不少. 使用原生的SoapClient库请求也是失败.只好用post来进行模拟了.代码贴出来,给大家参考一下. <?php namespace App\Services\Proxy; use Log; class Crm { private $host; private $namespace; private $app_secret; private $username; private $values; public functi

Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码

主要难点在于设置recv()与send()的超时时间,具体要注意的事项,请看代码注释部分,下面是代码: [cpp] view plaincopyprint? #include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <string.h> #ifdef _WIN32   ///