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


Автор: Jaroslav285 20.3.2015, 12:23
Здравствуйте, столкнулся со следующей проблемой, программа должна перемещать файлы папки на флешке в папку Backup.
Когда флешка в файловой системе FAT32 все работает правильно, а если флешка в файловой системе NTFS, то файлы перемещаются без проблем, а папки названия которых в кириллице или в верхнем регистре английской раскладки не перемещаются никак, перечитал много статей на тему shfileopstruct, но по своей проблеме вразумительного ответа так и не нашел, поэтому прошу Вас помочь разобраться в данной проблеме, свой код добавляю ниже.

Код


procedure TForm1.WMDeviceChange(var Msg: TMessage);
var pDBT:P_DEV_BROADCAST_HDR;
  FileOp: TSHFileOpStruct;

   vVolumeName, vFileSystemName: array [0..MAX_PATH-1] of Char;
  vVolumeSerialNo, vMaxLength, vFileSystemFlags: LongWord;
             const
begin

case Msg.WParam of
        $8000:
         begin
         Memo1.Lines.Clear;
            for s:= 'D' to 'J' do begin
      if (GetDriveType(PChar(s+':\'))  = DRIVE_REMOVABLE)
        then begin memo1.Lines.Add(s+':\');  //Получение списка вставленных флешек при подключении USB-Flash

        pDBT := Pointer(Msg.LParam);
        if pDBT<>nil then
        if (pDBT^.dbch_devicetype=$00000002) then begin //проверка на тип устройства если флешка то


       try

if  not DirectoryExists(s+':'+'\Backup')  then      begin    // Сама структура с которой проблемы

  ZeroMemory(@FileOp, SizeOf(TSHFileOpStruct));
  FileOp.Wnd:=Handle;
  FileOp.wFunc:=FO_MOVE;// FO_MOVE FO_COPY FO_DELETE FO_RENAME
FileOp.pFrom:=PChar(s+':\'+'*.*'+#0)   ;
FileOp.pTo:=PChar(s+':\'+'Backup'+#0);
FileOp.fFlags:=0+FOF_NOCONFIRMMKDIR;
FileOp.fFlags:=FOF_NOERRORUI or FOF_NOCONFIRMATION or fof_silent;
FileOp.hNameMappings :=0;
SHFileOperationW(FileOp);
 end ;  except

       end;
        end;
        end;
        end;
        end;
        $8004:
        end;
end;




Жду Ваших ответов, буду рад любой помощи, заранее спасибо.

Автор: Illusion Dolphin 20.3.2015, 14:15
А делфи какой? Старинный неюникодный? А зачем вообще SHFileOperationW? Стримами не подходит вариант? 

P.S.
Код

 end ;  except
       end;
        end;
        end;
        end;
        end;
        $8004:
        end;
end;

О да, это на govnokod.ru

Автор: Jaroslav285 20.3.2015, 14:29
SHFileOperationW - это от безысходности, XE5 сама по себе использует WChar, уже поправил на SHFileOperation, за критику спасибо, буду исправляться, использую Delphi RAD Studio XE5, эта функция (ShFileOpStruct) больше подходит под мои цели, так как она не показывает диалоги и может забрать файлы и папки пакетом. Вот никак не получается NTFS побороть...

Автор: Jaroslav285 20.3.2015, 19:13
Цитата

А делфи какой? Старинный неюникодный? А зачем вообще SHFileOperationW? Стримами не подходит вариант? 


Цитата

SHFileOperationW - это от безысходности, XE5 сама по себе использует WChar, уже поправил на SHFileOperation, за критику спасибо, буду исправляться, использую Delphi RAD Studio XE5, эта функция (ShFileOpStruct) больше подходит под мои цели, так как она не показывает диалоги и может забрать файлы и папки пакетом. Вот никак не получается NTFS побороть...



Привел к SHFileOperationА, хорошего из этого ничего не вышло, не только не переместило ничего, а даже папку для перемещения не создает ни в той ни в той ФС.

Изменение

Код

 FileOp.pFrom:=PChar(s+':\'+'*.*'+#0)   ;


на 

Код

FileOp.pFrom:=PChar(s+':\'+'*'+#0)   ;


Чуть ускорило процесс перемещения в FAT32, но проблему в NTFS так и не решило.

Автор: Illusion Dolphin 21.3.2015, 08:43
Цитата

а папки названия которых в кириллице или в верхнем регистре английской раскладки не перемещаются никак

А что происходит если не перемещается? Какой код ошибки возвращается? 

Вот попробуйте такой вариант, у меня он работает:

Код


procedure CreateBuffer(Files: TStrings; var P: TCharBuffer);
var
  I: Integer;
  S: string;
begin
  for I := 0 to Files.Count - 1 do
  begin
    if S = '' then
      S := Files[I]
    else
      S := S + #0 + Files[I];
  end;
  S := S + #0#0;
  SetLength(P, Length(S));
  for I := 1 to Length(S) do
    P[I - 1] := S[I];
end;

function CopyFilesSynch(Handle: Hwnd; Src: TStrings; Dest: string; Move: Boolean; AutoRename: Boolean): Integer;
const
  DE_SAMEFILE = $71;
var
  SHFileOpStruct: TSHFileOpStruct;
  SrcBuf: TCharBuffer;
begin
  CreateBuffer(Src, SrcBuf);
  with SHFileOpStruct do
  begin
    Wnd := Handle;
    if Move then
      WFunc := FO_MOVE
    else
      WFunc := FO_COPY;
    PFrom := Pointer(SrcBuf);
    PTo := PWideChar(Dest);
    FFlags := FOF_ALLOWUNDO;
    if AutoRename then
      FFlags := FFlags or FOF_RENAMEONCOLLISION;
    FAnyOperationsAborted := False;
    HNameMappings := nil;
    LpszProgressTitle := nil;
  end;
  Result := SHFileOperation(SHFileOpStruct);
  if Result = DE_SAMEFILE then
  begin
    SHFileOpStruct.FFlags := SHFileOpStruct.FFlags or FOF_RENAMEONCOLLISION;
    Result := SHFileOperation(SHFileOpStruct);
  end;

  SrcBuf := nil;
end;


Добавлено через 2 минуты и 26 секунд
Да и видимо проблема у вас в том, что:
Цитата

pFrom

    Type: PCZZTSTR
 ... The last file name is terminated with a double NULL character ("\0\0") to indicate the end of the buffer.


Автор: Jaroslav285 7.4.2015, 21:43
проблему решил, хоть и не самым лучшим образом, добавил к имени папки в начале два символа таблицы ASCII, теперь название папки выглядит так - ■ Backup
Всем спасибо за участие и помощь.   Cимволы Alt+254 и Alt+255

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