Удаление каталогов с вложенными файлами
download delFiles (64 & 32 bit).exe
//проверяем, корректны ли пути, указанные в файле.
//составляем итоговую строку-список путей(pFrom)
//запускаем удаление
//cd "C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin"
//x86_64-w64-mingw32-gcc.exe delFiles.c -lshlwapi -o delFiles.exe
// delFiles.exe
//cd "C:\Program Files (x86)\C-Free 5\mingw\bin"
//gcc.exe delFiles.c -lshlwapi -o delFiles32bit.exe
// delFiles32bit.exe
#include <stdio.h>
#include <windows.h>
#include <shlwapi.h>
typedef struct pathp {
char * path;
int length;
struct pathp * next;
} pathp;
int main(void)
{
pathp * first_ppathp = NULL;
pathp * next_ppathp = NULL;
int rez, retval, mem = 0, sumMem = 0;
int cc = 0;
char path[MAX_PATH]; // MAX_PATH = 260
char * n;
char * pFrom, * pFromN;
FILE * in = fopen("delFilesIni.txt", "r");
if (in == NULL) {
MessageBox(NULL, "Cannot open \"delFilesIni.txt\" file.", "_delFiles_", MB_OK);
exit (1);
}
/* Здесь вначате предполагается, что путь в первой строке будет корректным. Если нет,
то в цикле ищу этот путь. Нашёл первый путь. После этого в следующем(втором) цикле выбираю
все остальные пути. ( Это вместо одного цикла с определением первого и последующих путей
и всякими проверками )
Из-за этого есть повторные куски кода.
*/
if ( fgets(path, MAX_PATH+1, in) != NULL ){
n = strchr(path, '\n');
if (n != NULL)
*n = '\0';
retval = PathFileExists(path);
if (retval != 0 ){ //первый считаный из файла путь существует
first_ppathp = malloc(sizeof(pathp));
mem = strlen(path) + 1; // + \0
sumMem += mem;
first_ppathp -> path = (char*) malloc ( mem ); // выделение памяти под путь
strcpy (first_ppathp -> path, path);
first_ppathp -> length = mem;
first_ppathp -> next = NULL;
} else {
while ( fgets(path, MAX_PATH+1, in) != NULL ){ //остаются символы перевода строки
n = strchr(path, '\n');
if (n != NULL)
*n = '\0';
retval = PathFileExists(path);
if (retval != 0 ){
first_ppathp = malloc(sizeof(pathp));
mem = strlen(path) + 1;
sumMem += mem;
first_ppathp -> path = (char*) malloc ( mem ); // выделение памяти под путь
strcpy (first_ppathp -> path, path);
first_ppathp -> length = mem;
first_ppathp -> next = NULL;
break;
}
}
}
next_ppathp = first_ppathp;
////////////////////////////////////////////////
while ( fgets(path, MAX_PATH+1, in) != NULL ){ //остаются символы перевода строки
n = strchr(path, '\n');
if (n != NULL)
*n = '\0';
retval = PathFileExists(path);
if (retval == 0 )
continue;
next_ppathp -> next = malloc(sizeof(pathp)); //выделение памяти под структуру
next_ppathp = next_ppathp -> next;
mem = strlen(path) + 1;
sumMem += mem;
next_ppathp -> path = (char*) malloc ( mem ); // выделение памяти под путь
strcpy (next_ppathp -> path, path);
next_ppathp -> length = mem;
next_ppathp -> next = NULL;
}
}
fclose(in);
if ( first_ppathp == NULL ){
MessageBox(NULL, "Нет существующих путей. Возможно, каталоги уже удалены.", "_delFiles_", MB_OK);
return 0;
}
sumMem += 1;
pFrom = malloc(sumMem);
pFromN = pFrom;
next_ppathp = first_ppathp;
while (next_ppathp != NULL){
strcpy (pFromN, next_ppathp -> path);
pFromN = pFromN + next_ppathp -> length;
next_ppathp = next_ppathp-> next;
}
*pFromN = '\0'; // or pFromN[0] // => '\0\0'
//очистка памяти
while (first_ppathp != NULL){
next_ppathp = first_ppathp-> next;
free(first_ppathp->path);
free(first_ppathp);
first_ppathp = next_ppathp;
}
//FILE * ff = fopen("ff.txt", "w");
//fwrite(pFrom, sizeof(char), sumMem, ff);
//fclose(ff);
LPSHFILEOPSTRUCTA lpFileOp;
lpFileOp = malloc(sizeof(SHFILEOPSTRUCTA));
lpFileOp -> hwnd = 0;
lpFileOp -> wFunc = FO_DELETE;
lpFileOp -> pFrom = pFrom; // "C:\dir1\0C:\dir2\0C:\dir3\0\0";
lpFileOp -> pTo = NULL;
//lpFileOp -> fFlags = FOF_ALLOWUNDO; // при удалении - "удаление" в корзину. Если каталоги заняты - появляется диалог
lpFileOp -> fFlags = 0; // удаление безвозвратно. Появляется диалог.
//lpFileOp -> fAnyOperationsAborted
lpFileOp -> hNameMappings = NULL;
lpFileOp -> lpszProgressTitle = NULL;
rez = SHFileOperationA( lpFileOp );
if (rez == 0 ){
//MessageBox(NULL, "ok!", "_delFiles_", MB_OK);
//if (lpFileOp -> fAnyOperationsAborted != 0)
// MessageBox(NULL, "Any operations aborted.", "_delFiles_", MB_OK);
}else {
sprintf(path, "Возможно каталоги заняты запущенным приложением. error = %d (%x)", rez, rez);
MessageBox(NULL, path, "_delFiles_", MB_OK);
}
return 0;
}
// https://docs.microsoft.com/ru-ru/windows/desktop/api/shellapi/nf-shellapi-shfileoperationa
// https://docs.microsoft.com/ru-ru/windows/desktop/api/shellapi/ns-shellapi-_shfileopstructa
Список удаляемых каталогов/файлов
Запуск. Удаление.
Комментарии