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


Автор: Antony41 12.5.2009, 21:37
Привет!
Вот обычная фун-я перемещения файла в корзину.

Код

function FRecycle(const FileName: string; Wnd: HWND = 0): Boolean;
var
  FileOp: TSHFileOpStruct;
begin
  FillChar(FileOp, SizeOf(FileOp), 0);
  if Wnd = 0 then
    Wnd := Application.Handle;
  FileOp.Wnd := Wnd;
  FileOp.wFunc := FO_DELETE;
  FileOp.pFrom := PAnsiChar(FileName);
  FileOp.fFlags :=
//флаги определяющие параметры операции.
     FOF_ALLOWUNDO //сохраняет информацию о возможной отмене операции.
  or FOF_FILESONLY //выполняет операцию только для файлов, если задана маска файлов.
  or FOF_NOCONFIRMATION //отвечает "Да для всех" на все вопросы.
  or FOF_NOERRORUI //Не отображает пользовательский интерфейс при ошибке.
  or FOF_SILENT; //не показывает прогресс бар отображающий ход операции.

  //or FOF_MULTIDESTFILES //указывает, что pTo описывает несколько файлов (по одному на каждый файл источника) вместо одного каталога, куда должны быть помещены исходные файлы.
  //FOF_NOCONFIRMMKDIR //не требует подтверждения создания нового каталога.
  //or FOF_NO_CONNECTED_ELEMENTS //С версии 5.0. Не перемещает связанные файлы как группу. Только перемещает указанные файлы
  //or FOF_NOCOPYSECURITYATTRIBS //С версии 4.71. Не копирует атрибуты безопасности файла.
  //FOF_NORECURSION //Не поддерживает рекурсивные операции в подкаталогах, работает только в локальном каталоге.
  //FOF_RENAMEONCOLLISION //присваивает файлу новое имя при операциях копирования, перемещения или переименования, если файл с указанным именем уже существует.
  //or FOF_SIMPLEPROGRESS; //отображает окно прогресс бара, но не показывает имен файлов.
  //FOF_WANTMAPPINGHANDLE {Определяет использование поля hNameMappings . Хендл объекта должен быть освобожден функцией SHFreeNameMappings . Она объявлена в ShellApi как процедура
  //SHFreeNameMappings(hNameMappings: THandle);}

  Result := (SHFileOperation(FileOp) = 0) and (not
    FileOp.fAnyOperationsAborted);
end;




Категорически отказывается удалить файл 
C:\Стас Михайлов\06 S. Mihailov - Luchshie pesni (2007)\02 Mama.mp3

Стоит его только переименовать
C:\Стас Михайлов\06 S. Mihailov - Luchshie pesni (2007)\02 Mama1.mp3
и всё встаёт на своё место.
Переименовываю обратно и снова нифига не работает smile

Файл не занят ни какими процессами и стандартным методом удаляется (через explorer), хотя и тут функция ShellAPI

Аттрибуты тоже сняты. Что же это может быть? smile 
зы длина строки и размер файла значения не меняют.

M
Rrader
Antony41, название темы должно кратко отражать ее суть. "Странная ошибка" - это не дело, у такой темы 100% в будущем будет странная судьба :)

Автор: Mechanic 12.5.2009, 22:31
Попробуй ноль в конце имени добавить

Код

FileOp.pFrom := PAnsiChar(FileName+#0);
 

Автор: kami 12.5.2009, 22:52
Цитата(Antony41 @  12.5.2009,  21:37 Найти цитируемый пост)
Категорически отказывается удалить файл 

Вообще-то все функции возвращают код ошибки, если что-то отказываются делать.
Код возвращается либо в результате ф-и, либо доступен через GetLastError.
Что означает код ошибки можно посмотреть в http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

В данном случае коды ошибок имеются http://msdn.microsoft.com/en-us/library/bb762164(VS.85).aspx

Узнаете что за ошибка - можно будет ее устранять.

Автор: Keeper89 12.5.2009, 23:03
Попробуйте заменить PAnsiChar на PChar.

Автор: kami 12.5.2009, 23:25
Цитата(Keeper89 @  12.5.2009,  23:03 Найти цитируемый пост)
Попробуйте заменить PAnsiChar на PChar.

Это почему?
SHFileOperation доступна и в Ansi и в Unicode версиях.
Какая из них задействуется по умолчанию - дело версии Delphi, о которой тут ни слова не было.
Вроде, D2009 только задействовало Unicode по умолчанию?
В любом случае - если PChar=PAnsiChar, то и SHFileOperation=SHFileOperationA по умолчанию.

Добавлено через 1 минуту и 14 секунд
А если SHFileOperation=SHFileOperationW,
то PChar=PWideChar.
Так что явное приведение к Ansi тут может быть лишним.

Автор: Akella 12.5.2009, 23:48
Цитата(kami @  12.5.2009,  22:52 Найти цитируемый пост)
Что означает код ошибки можно посмотреть в MSDN

или у нас на форуме
http://forum.vingrad.ru/index.php?showtopic=237714&view=findpost&p=1733249

Автор: Keeper89 12.5.2009, 23:50
У меня в D2007 работают оба варианта (PAnsiChar и PChar, хотя все-таки это разные вещи). Надо смотреть либо код ошибки, либо есть особенности в конкретной версии Delphi.

Автор: kami 13.5.2009, 00:05
Цитата(Keeper89 @  12.5.2009,  23:50 Найти цитируемый пост)
хотя все-таки это разные вещи.

Это разные вещи для D2009, поскольку там PChar=PWideChar.
Во всех предыдущих PChar=PAnsiChar, см. Character pointers в хелпе Delphi.
Цитата(Keeper89 @  12.5.2009,  23:50 Найти цитируемый пост)
У меня в D2007 работают оба варианта (PAnsiChar и PChar

Само собой, т.к. там вызывается Ansi версия SHFileOperation и PChar=PAnsiChar. Т.о. в итоге вызывается одна и та же ф-я с одними и теми же параметрами.

За сим умолкаю и прошу прощения за отклонение от темы ветки.

Автор: Mechanic 13.5.2009, 07:34
В самом деле, некоторые функи из этой оперы требуют дополнительного нуля после имени файла (см пост № 2).
Этот нуль призван ограничивать список имен, если таковое не одно. Но если даже оно одно, то нуль этот не помешает.

Just try. ;-)

Автор: CodeMonkey 13.5.2009, 09:13
http://msdn.microsoft.com/en-us/library/bb759795(VS.85).aspx:
Цитата
SHFILEOPSTRUCT Structure
...
pFrom
  Note: This string must be double-null terminated.

Автор: Antony41 13.5.2009, 09:26
Цитата(Keeper89 @  12.5.2009,  23:03 Найти цитируемый пост)
Попробуйте заменить PAnsiChar на PChar.


Пробовал не помогает

Цитата(kami @  12.5.2009,  23:25 Найти цитируемый пост)
дело версии Delphi, о которой тут ни слова не было

Delphi 7 Studio

Цитата(kami @  12.5.2009,  22:52 Найти цитируемый пост)
Вообще-то все функции возвращают код ошибки, если что-то отказываются делать.

Ошибка: Не удаётся удалить файл. Не удаётся произвести чтение из файла или с диска.

Цитата(Mechanic @  13.5.2009,  07:34 Найти цитируемый пост)
если таковое не одно. Но если даже оно одно, то нуль этот не помешает.

Файл один. 
помогло, но всё таки странно почему...
Может ноль следует добавить и в функцию DeleteFile? входящую в комплект SysUtils?

Автор: CodeMonkey 13.5.2009, 10:31
Цитата
помогло, но всё таки странно почему...

Да потому что в документации так написано.

Автор: Antony41 13.5.2009, 15:24
Цитата(CodeMonkey @  13.5.2009,  09:13 Найти цитируемый пост)
SHFILEOPSTRUCT Structure...pFrom  Note: This string must be double-null terminated.

вот блин точно... для DeleteFile нужно применять #0?

Автор: CodeMonkey 13.5.2009, 16:10
Нет, конечно же.

Подсказка: функция SHFileOperation работает с кучей файлов, вот почему ей нужен двойной разделитель, т.к. группа файлов задаётся так: 'файл1'#0'файл2'#0'файл3'#0#0.

Автор: MetalFan 13.5.2009, 16:19
Цитата(Antony41 @  13.5.2009,  15:24 Найти цитируемый пост)
для DeleteFile нужно применять #0? 

во выразился... куда применять? зачем?)

Автор: Antony41 13.5.2009, 21:24
всё понятно Спасибо всем кто учавствовал тема закрыта

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