Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > удаление с помощью SHFileOperation


Автор: shuttle 3.2.2009, 16:10
Использую SHFileOperation для удаления каталога. 

Код

SHFILEOPSTRUCT sh

sh.wFunc = FO_DELETE;    
sh.pTo = L"NULL";
sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
sh.hNameMappings = 0;
sh.lpszProgressTitle = NULL;

sh.pFrom = dir_temp     //path каталога
SHFileOperation (&sh); 


В итоге каталог остается на месте. GetLastError - выводит 6 - ERROR_INVALID_HANDLE(The handle is invalid). В структуре SHFILEOPSTRUCT есть параметр hwnd.
В MSDN написано hwnd - Window handle to the dialog box to display information about the status of the file operation. Я так понимаю для диалогового окна. А какое  значение hvnd должно быть в консольном приложении. Или причина не в нем.

Автор: GoldFinch 3.2.2009, 16:22
читай описание функции, там все написано

Автор: shuttle 4.2.2009, 06:41
что-то странное пошло.

если пишу так 
Код

sh.pFrom = dir_temp     //path каталога 


то SHFileOperation позвращает 1026. - неудачное выполнение (причем не могу найти описание этой ошибки).

если
Код

sh.pFrom = L"d:\\catalog"     //path каталога 

то все нормально. 

В чем может быть причина?

Автор: shuttle 4.2.2009, 10:20
вроде кое-что прояснилось.
у  sh.pFrom тип LPCTSTR, у меня переменная dir_temp типа wchar_t, оба Unicod-ские при копировании 
Код

sh.pFrom=dir_temp

компилятор не ругается, но видимо преобразование выполняется неправильно. И соответственно SHFileOperation (&sh); выполняется с ошибкой. Явное преобразование тоже не помогает
Код

sh.pFrom=(LPCTSTR)dir_temp


объявлять dir_temp типа LPCTSTR накладно, надо будет другую часть программы менять. 
Как правильно преобразовать из wchar_t к типу LPCTSTR?





Автор: Rififi 4.2.2009, 11:09
shuttle, 

sh.pFrom=(LPCTSTR)dir_temp
эту жуть убери, пока тебе руки не оторвали (:

пути в функции должны завершаться двойным нулём _T('\0')

Автор: shuttle 4.2.2009, 11:40
Цитата

пути в функции должны завершаться двойным нулём _T('\0') 


так тоже пробовал не прокатывает.

Автор: GoldFinch 4.2.2009, 12:16
посмотри под отладчиком что там реально передается

Автор: shuttle 4.2.2009, 12:57
Цитата

посмотри под отладчиком что там реально передается 


Смотрел, строки полностью совпадают.

Тут вот еще с переменными типа wchar_t покопался.
Код

wchar_t dir_temp[255];
//...
// сдесь что происходит
// в dir_temp заносится значение "d:\\catalog\0"
// ...
sh.pFrom=dir_temp
FileOperation (&sh); 

так не срабатывает

а если инициализировать при объявлении(причем неважно какими данными), то нормально
Код

wchar_t dir_temp[255]=L"init";
//...
// сдесь что происходит
// в dir_temp заносится значение "d:\\catalog\0"
// ...
sh.pFrom=dir_temp
FileOperation (&sh); 

так срабатывает

В чем проблема????? Чудес же не бывает.



Автор: GoldFinch 4.2.2009, 13:07
значит не совпадают.
и выложи код, вместо "// сдесь что происходит"

Добавлено через 4 минуты и 26 секунд
попробуй заодно обнулить SHFILEOPSTRUCT

Автор: Rififi 4.2.2009, 13:33
shuttle, 
кусок из рабочего кода

Код
                std::_tstring dir = dir_path + PathSeparator + fd.cFileName;
                dir += _T('\0'); // дополнительный символ-терминатор нужен для API-функции SHFileOperation

                SHFILEOPSTRUCT fs;
                fs.hwnd = NULL;
                fs.wFunc = FO_DELETE;
                fs.pFrom = dir.c_str();
                fs.pTo = NULL;
                fs.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION;
                if (::SHFileOperation(&fs))    // 0 == success
                {
                    ::FindClose(hFile);
                    LOG_ERROR(L"Cleanup destination directory failed, Err: " << GetMessageFromWin32W());
                    THROW_EXCEPTION(EXPORT_ERROR_FROM_WIN32);
                }

Автор: shuttle 4.2.2009, 13:59
фрагмент текста

Код

//глобальные переменные
wchar_t lpClientDirTemp[255];          //название временной папки клиента
wchar_t lpCurrentUser[255];             //имя текущего клиента-имя каталога клиента
...
...
...
void AddInArhiv()
{
wchar_t list_file[255]=L"init";

file_dir = FindFirstFile(lpListTempDirTemp, &ffd_dir);    
if(file_dir!=INVALID_HANDLE_VALUE)
{
   do
   {            
        if(strcmp((char*)ffd_dir.cFileName,".")!=0 && strcmp((char*)ffd_dir.cFileName,"..")!=0)
        {                
             if ((ffd_dir.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0)
             {                    
                  if(ffd_dir.cFileName[0]>=L'0' && ffd_dir.cFileName[0]<=L'9')
                  
                  swprintf(list_file, L"%s\\%s\\%s\0", lpClientDirTemp,ffd_dir.cFileName, lpCurrentUser);   
                  
                  swprintf(path_save_zip, L"%s\\%s.zip\0", path_save,ffd_dirdir.cFileName);                              swprintf(list_file_res, L"%s\\%s\\*.*\0", list_file,ffd_dirdir.cFileName);

                  //запуск архиватора PKZIP25.exe
                  int res=_wspawnlp(_P_WAIT,L"\\PKZIP25.exe",L"pkzipc",L"-add",L"-silent",L"-zipdate=newest",path_save_zip,list_file_res,NULL);

                   //удаляю list_file
                   sh.pFrom=list_file;
                   answ= SHFileOperation(&sh);

             }
         }
     }
     while(FindNextFile(file_dir,&ffd_dir));
}
FindClose(file_dir);
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)