Поиск и удаление в субдиректориях

Тема в разделе "WASM.BEGINNERS", создана пользователем vg, 10 июн 2007.

  1. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Кстати да, IceStudent совершенно прав, я как-то это проглядел.


    Код (Text):
    1. ...
    2. or    WFD.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
    3. jnz      @F
    4. ...
     
  2. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Маска задается как "*".

    Вот что получилось в итоге.
    Код (Text):
    1. FindandDelete proc Directory :DWORD
    2.     LOCAL SearchFilter[MAX_PATH] :byte
    3.     LOCAL CurFileName[MAX_PATH]  :byte
    4.     LOCAL WFD                    :WIN32_FIND_DATA
    5.             LOCAL hFind: DWORD
    6.  
    7.     invoke SetCurrentDirectory,Directory
    8.     invoke lstrcpy,addr SearchFilter,Directory
    9.     invoke lstrcat,addr SearchFilter,addr pathanymask
    10.     invoke FindFirstFile,addr SearchFilter,addr WFD
    11.     inc eax
    12.     je exit2
    13.     dec eax
    14.     mov hFind,eax
    15. deleting:
    16.     invoke FindNextFile,hFind,addr WFD
    17.     xchg eax,ecx
    18.     jecxz exit1
    19.        test    WFD.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
    20.        jz      @F
    21.     invoke lstrcmp,addr WFD.cFileName,addr updirmask
    22.     xchg eax,ecx
    23.     jecxz deleting
    24.     invoke lstrcpy,addr CurFileName,Directory
    25.     invoke lstrcat,addr CurFileName,addr slash
    26.     invoke lstrcat,addr CurFileName,addr WFD.cFileName
    27.     invoke FindandDelete,addr CurFileName
    28.     jmp deleting
    29. @@:
    30.     invoke DeleteFile,addr WFD.cFileName
    31.     jmp deleting
    32. exit1:
    33.     invoke FindClose,hFind
    34.             ret
    35. exit2:
    36. FindandDelete endp
     
  3. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    приведенный код не удаляет всех файлов - SetCurrentDirectory устанавливает директорию глобально
    вот правильный код:
    Код (Text):
    1. FindandDelete proc Directory :DWORD
    2.     LOCAL SearchFilter[MAX_PATH] :byte
    3.     LOCAL CurFileName[MAX_PATH]  :byte
    4.     LOCAL CurDir[MAX_PATH]      :BYTE
    5.     LOCAL WFD                    :WIN32_FIND_DATA
    6.             LOCAL hFind: DWORD
    7.     invoke      GetCurrentDirectory,MAX_PATH,addr CurDir
    8.     invoke SetCurrentDirectory,Directory
    9.     invoke lstrcpy,addr SearchFilter,Directory
    10.     invoke lstrcat,addr SearchFilter,addr pathanymask
    11.     invoke FindFirstFile,addr SearchFilter,addr WFD
    12.     inc eax
    13.     je exit2
    14.     dec eax
    15.     mov hFind,eax
    16. deleting:
    17.     invoke FindNextFile,hFind,addr WFD
    18.     xchg eax,ecx
    19.     jecxz exit1
    20.        test    WFD.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
    21.        jz      @F
    22.     invoke lstrcmp,addr WFD.cFileName,addr updirmask
    23.     xchg eax,ecx
    24.     jecxz deleting
    25.     invoke lstrcpy,addr CurFileName,Directory
    26.     invoke lstrcat,addr CurFileName,addr slash
    27.     invoke lstrcat,addr CurFileName,addr WFD.cFileName
    28.     invoke FindandDelete,addr CurFileName
    29.     jmp deleting
    30. @@:
    31.     invoke DeleteFile,addr WFD.cFileName
    32.     jmp deleting
    33. exit1:
    34.     invoke FindClose,hFind
    35. exit2:
    36.     invoke      SetCurrentDirectory,addr CurDir
    37.             ret
    38. FindandDelete endp
     
  4. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    wasmer
    Да, вы отлично это заметили! Хотя лучше всего не играться с текущей директорией - т.к. это плохой стиль - а делать полный путь для удаления походу вызова DeleteFile.
     
  5. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Вот мой древний-предревний сишный вариант рекурсивного поиска с вызовом хэндлера
    Код (Text):
    1. //---------------------------------------------------------------------------
    2. typedef void    (*HANDLER)(const char *, const WIN32_FIND_DATA *);
    3. int find(const char *, const char *, HANDLER, WIN32_FIND_DATA *);
    4. //---------------------------------------------------------------------------
    5. int find(const char *c, const char *mask, HANDLER handler, WIN32_FIND_DATA *WFD){
    6. char    buf[MAX_PATH];
    7. int     l;
    8. int static  found(0);
    9. HANDLE  h;
    10.  
    11.     if(c && (*c))
    12.     {
    13.         strcpy(buf,c);l=strlen(buf);
    14.         if(buf[l-1] != '\\')
    15.         {
    16.             strcat(buf,"\\");l++;
    17.         }
    18.     }
    19.     else
    20.     {
    21.         strcpy(buf,".\\");l=2;
    22.     }
    23.     strcat(buf,mask);
    24.     if((h = FindFirstFile(buf, WFD)) != INVALID_HANDLE_VALUE)
    25.     {
    26.         buf[l]=0;
    27.         do{
    28.             if(*(WFD->cFileName) != '.')
    29.             {
    30.                 found++;
    31.                 handler(buf, WFD);
    32.             }
    33.         }while(FindNextFile(h, WFD));
    34.         FindClose(h);
    35.     }
    36.  
    37.     buf[l]=0;strcat(buf,"*");
    38.     if((h = FindFirstFile(buf, WFD)) != INVALID_HANDLE_VALUE)
    39.     {
    40.         do{
    41.             if((WFD->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (*(WFD->cFileName) != '.'))
    42.             {
    43.                 buf[l]=0;strcat(buf,WFD->cFileName);
    44.                 find(buf, mask, handler, WFD);
    45.             }
    46.         }while(FindNextFile(h, WFD));
    47.         FindClose(h);
    48.     }
    49.  
    50. return  found;
    51. }
    52. //---------------------------------------------------------------------------
    Хотя для удаления и не подойдёт - вид обхода не тот, но для поиска - норм. Да и переделать - как 2 пальца -> второй цикл перенести перед первым.
     
  6. vg

    vg New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2007
    Сообщения:
    475
    Не понимаю.
    Можно разъяснить?
    Т.е. глобально?
     
  7. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    vg
    Ну ты зашел например рекурсивно в какую-нить директорию, в этом рекурсивном вызове сделал SetCurrentDirectory. Потом вернулся из рекурсивного вызова, текущая директория уже изменилась, а ты пытаешься удалить файлы в другой директории - на уровень выше, и при этом текущая директория другая, и изменяется она в начале вызова функции.