CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Kopiowanie folderu

Kopiowanie folderu

dział ogólny

Kopiowanie folderu

Nowy postprzez Gepcio » wtorek, 22 maja 2012, 20:42

Problem być może jest prosty do rozwiązania ale siedzę nad nim cały dzień i szczerze mam dość. Otóż próbuję skopiować pliki z jakiegoś folderu do folderu temp. I teraz próbowałem na następujące sposoby:

Pierwszy:
KOD cpp:     UKRYJ  
SHFILEOPSTRUCT sf;
        memset(&sf,0,sizeof(sf));
        sf.hwnd = 0;
        sf.wFunc = FO_COPY;
        sf.pFrom = (ZipFilePath+"\\*.*").t_str();
        sf.pTo = TempPath.t_str();
        sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
        int n = SHFileOperation(&sf);
        if( n == 0)
        {
                ShowMessage("Success");
        }
        else
        {
                ShowMessage("Failed");
        }


Drugi:
KOD cpp:     UKRYJ  
system(("copy "+ZipFilePath+"\\*.* "+TempPath).t_str());


To są dwa najbardziej chyba pasujące, pozostałe to żenada była... Nie wiem co dalej... Może ktoś wpadnie na coś ciekawego... Niby pliki się skopiują ale w samym katalogu ich nie ma... Komputer robi mnie w konia :p

Za ten post autor Gepcio otrzymał podziękowanie od:
sebaskow
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Firefox

Re: Kopiowanie folderu

Nowy postprzez mckri » środa, 23 maja 2012, 09:27

A jaki masz numer błedu systemu podczas kopiowania? (Możesz to sprawdzić poprzez 'GetSystemError()' i sprawdzić sobie treść błędu na stronie MSDN albo przetłumaczyć poprzez funkcję 'FormatMessage')
Wartość w zmiennej 'TempPath' masz wpisane na sztywno czy pobierasz ze zmiennej środowiskowej %TEMP%?
Istotna może być również sama lokalizacja docelowa - czy ma znak '\' na końcy ściezki czy nie?
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows 7Opera

Re: Kopiowanie folderu

Nowy postprzez polymorphism » środa, 23 maja 2012, 11:03

KOD cpp:     UKRYJ  
sf.pFrom = (ZipFilePath+"\\*.*").t_str();

Jeśli mnie pamięć nie myli, pFrom powinna się kończyć podwójnym \0, ponieważ pole to powinno zawierać listę plików do skopiowania w postaci sekwencji c-stringów, zakończonych pustym c-stringiem, czyli np. coś takiego: plik1\0plik2\0plik3\0\0.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Cyfrowy Baron » środa, 23 maja 2012, 16:12

Jak zauważył polymorphism element pFrom, ale nie tylko bo element pTo muszą się kończyć \0. Twój kod może więc wyglądać tak:

KOD cpp:     UKRYJ  
String ZipFilePath = "c:\\FolderTest";
 String TempPath = "c:\\temp";

 SHFILEOPSTRUCT sf;
 memset(&sf,0,sizeof(sf));
 sf.hwnd = 0;
 sf.wFunc = FO_COPY;
 sf.pFrom = ( ZipFilePath + "\\*.*\0").t_str();
 sf.pTo = (TempPath + "\0").t_str();
 sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
 int n = SHFileOperation(&sf);
 if( n == 0)
 {
  ShowMessage("Success");
  }
  else
  {
   ShowMessage("Failed");
  }


U mnie takie kopiowanie za pomocą latających folderów działa.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Gepcio » środa, 23 maja 2012, 21:09

No temp pobieram ze zmiennej środowiskowej. Zaraz spróbuję tego z podwójnym /0/0 i powiem jak poszło.
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Firefox

Re: Kopiowanie folderu

Nowy postprzez polymorphism » środa, 23 maja 2012, 22:25

Cyfrowy Baron napisał(a):
KOD cpp:     UKRYJ  
...
sf.pFrom = ( ZipFilePath + "\\*.*\0").t_str();
 

To nie przejdzie, ponieważ to zero w literale nie zostanie potraktowane jako dodatkowy znak, który trzeba dodać do sumy obu stringów. Będzie potraktowany po prostu jako koniec c-stringa i dodatkowe zero za nim zostanie zignorowane.

Tak powinno być ok:
KOD cpp:     UKRYJ  
basic_string<TCHAR> s( ZipFilePath.t_str() );

s += TEXT("\\*.*");
s += TEXT('\0');

...

sf.pFrom = s.c_str();
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Cyfrowy Baron » czwartek, 24 maja 2012, 04:50

polymorphism napisał(a):To nie przejdzie,


Nie napisałbym tego kodu bez przetestowania. Rzecz w tym, że u mnie w C++Builder 2010 to działa niezależnie od tego, czy umieszczę tam ten znak czy nie, to znaczy, że tak:

KOD cpp:     UKRYJ  
 sf.pFrom = ( ZipFilePath + "\\*.*").t_str();
 sf.pTo = (TempPath).t_str();


też działa.
Masz jednak rację co do tego, że to nie jest poprawne. Zrobiłem to też tak licząc, że zadziała:

KOD cpp:     UKRYJ  
 String ZipFilePath = "c:\\FolderTest";
 String TempPath = "c:\\temp";

 wchar_t wFrom[MAX_PATH];
 wchar_t wTo[MAX_PATH];

 swprintf(wFrom, L"%s", (ZipFilePath + "\\*.*").t_str());
 wcscat(wFrom, L"\0");

 swprintf(wTo, L"%s", TempPath.t_str());
 wcscat(wTo, L"\0");

 SHFILEOPSTRUCT sf;
 memset(&sf,0,sizeof(sf));
 sf.hwnd = 0;
 sf.wFunc = FO_COPY;
 sf.pFrom = wFrom;
 sf.pTo = wTo;
 sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
 int n = SHFileOperation(&sf);
 if( n == 0)
 {
  ShowMessage("Success");
  }
  else
  {
   ShowMessage("Failed");
  }


ale nie działa.

Problem z tym, że Twój kod też nie zadziała, gdyż nie można użyć std::basic_string dla typu Unicode komunikat błędu:


[BCC32 Error] Unit1.cpp(67): E2108 Improper use of typedef 'std::wstring'

Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez polymorphism » czwartek, 24 maja 2012, 09:56

Problem z tym, że Twój kod też nie zadziała, gdyż nie można użyć std::basic_string dla typu Unicode komunikat błędu:

W kodzie, który podałem był błąd, o jeden nawias za dużo było - poprawiłem. Pisząc ten kod założyłem, że t_str zwraca łańcuch char[] lub wchat_t[] w zależności od trybu kompilacji (to t do czegoś zobowiązuje w końcu). Ale jeśli zawsze zwraca łańcuch unikodowy, wtedy (jaki sens jest tej metody?) po prostu wystarczy użyć wstringa, tylko trzeba także użyć unikodowej wersji funkcji SHFileOperation.

--- dodane ---

Przejrzałem dokumentację i wynika z niej, że metoda t_str jest deprecated i teraz zwraca to samo, co metoda c_str, czyli wchar_t*. Zatem kod powinien wyglądać tak:
KOD cpp:     UKRYJ  
wstring s( ZipFilePath.c_str() );
s += L"\\*.*";
s += L'\0';

SHFILEOPSTRUCTW sf;
...

sf.pFrom = s.c_str();
...

int n = SHFileOperationW(&sf);
 
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Cyfrowy Baron » czwartek, 24 maja 2012, 17:20

polymorphism napisał(a):Przejrzałem dokumentację i wynika z niej, że metoda t_str jest deprecated i teraz zwraca to samo, co metoda c_str, czyli wchar_t*.


Tylko jeżeli mapowanie jest ustawione na wchar_t a nie char. Przy ustawieniu mapowania na char do konwersji na Unicode trzeba używać t_str(), a dla char c_str(). Przy mapowaniu na wchar_t obydwie metody działają tak samo.



Wydaje mi się, że można to zrobić prościej za pomocą funkcji swprintf, gdyż ta funkcja na końcu zawsze stawia NULL. Twój sposób z wstring oczywiście zadziała, ale dla mnie osobiście bardziej przyjaźnie wygląda kod z funkcją sprint (AnsiString) i swprintf (UnicodeString).

KOD cpp:     UKRYJ  
 String ZipFilePath = "c:\\FolderTest";
 String sFile = "*.*";
 String TempPath = "c:\\temp";

 wchar_t wPathFrom[MAX_PATH + 1] = {0};
 wchar_t wPathTo[MAX_PATH + 1] = {0};

 swprintf( wPathFrom, L"%s\\%s", ZipFilePath.c_str(), sFile.c_str() );
 swprintf( wPathTo, L"%s", TempPath.c_str() );

 SHFILEOPSTRUCT sf;
 memset(&sf,0,sizeof(sf));
 sf.hwnd = 0;
 sf.wFunc = FO_COPY;
 sf.pFrom = wPathFrom;
 sf.pTo = wPathTo;
 sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
 int n = SHFileOperation(&sf);
 if( n == 0)
 {
  ShowMessage("Success");
  }
  else
  {
   ShowMessage("Failed");
  }


U mnie to działa prawidłowo.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez polymorphism » czwartek, 24 maja 2012, 18:11

Tylko jeżeli mapowanie jest ustawione na wchar_t a nie char.

Na początku tak założyłem, ale z tego, co pisałeś i jest w dokumentacji wynika, że w nowszych wersjach środowiska tak nie jest. Według tej strony t_str zawsze zwraca wchar_t*:
The UnicodeString.t_str() function now always returns wchar_t* regardless of the current _TCHAR Mapping.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Cyfrowy Baron » czwartek, 24 maja 2012, 18:56

Masz rację, zaczęło mi się już to trochę mieszać. t_str zawsze zwraca wchar_t podczas gdy c_str() zwraca wchar_t przy mapowaniu na wchar_t lub char przy przy mapowaniu na char, dlatego jeżeli nie ma innej potrzeby najlepiej używać metody c_str().
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez polymorphism » czwartek, 24 maja 2012, 20:14

Według tej samej dokumentacji c_str także zwraca tylko wchar_t* dla UnicodeString (i pewnie dlatego t_str jest deprecated, ponieważ robi dokładnie to samo co c_str). Zmiana mapowania nie ma związku z VCL-em, ponieważ cały jest zaimplementowany jako biblioteka unikodowa.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kopiowanie folderu

Nowy postprzez Cyfrowy Baron » piątek, 25 maja 2012, 05:12

polymorphism napisał(a):Według tej samej dokumentacji c_str także zwraca tylko wchar_t* dla UnicodeString


Dokładnie odwrotnie jest niż to podałem, ale to też zależy od środowiska, czyli to t_str() zwraca char przy mapowaniu na char, ale tylko w środowisku do wersji 2010, w XE - nie wiem, ale w XE2 obie funkcje zwracają wchar_t.

W XE2 żeby przekonwertować UnicodeString na char trzeba zrobić tak niezależnie od mapowania.

KOD cpp:     UKRYJ  
 AnsiString( /*zmienna UnicodeString */).c_str();


Mapowanie zmienia w zasadzie tylko typy argumentów, których oczekują niektóre funkcję, no i t_str() nie ma zastosowania do AnsiString.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 6 gości