Poważne błędy w FindFirst w Delphi

0

Prawdopodobnie w funkcji FindFirst są dwa poważne problemy z wyszukaniem plików.

1. Wyszukanie ukrytych folderów:
http://www.tek-tips.com/viewthread.cfm?qid=1418012

2. Wyszukiwanie wszystkich plików w Vista/7 jest nieprawidłowe (pewne pliki mają inne atrybuty niż jest w dokumentacji):
http://groups.google.com/group/pl.comp.lang.delphi/browse_thread/thread/d14f93c0f1fa8cbd/12de0fce403ee354?#12de0fce403ee354
http://bugs.freepascal.org/view.php?id=9440

Są to na tyle poważne problemy, że nawet Delphi 2010 nie przynosi ich naprawienia.

Czy ktoś spotkał się już z tymi problemami ?
Myślę, że dyskusja na ten temat jest wskazana, bo w nowym systemie Windows7 i Viście dzieją się cuda z wyszukiwaniem !

no cóż... może i trzeci błąd to jest :
http://groups.google.com/group/pl.comp.lang.delphi/browse_thread/thread/dbce08153c397fa2

0

Google nie boli:

If you are writing a 32-bit application to list all the files in a directory and the application may be run on a 64-bit computer, you should call the Wow64DisableWow64FsRedirectionfunction before calling FindFirstFile and call Wow64RevertWow64FsRedirection after the last call to FindNextFile. For more information, see File System Redirector.

Już nie mówię o tym, że w Vista można używać

FindFirstFileTransacted

.

0

Nie znane funkcje... więc jak je wywołać ? Już nie mówiąc o tym, że wywołać je chyba trzeba tylko w systemie 64-bitowym w aplikacji 32-bitowej.

Wow64DisableWow64FsRedirection
Wow64RevertWow64FsRedirection
FindFirstFileEx
FindFirstFileTransacted

A my tu mówimy o systemie Windows Vista/7 32-bit i aplikacji 32-bit.

Poza tym gdzie są Misiekd i olesio ?

Czy na prawdę nikt nie potrafi się sensownie wypowiedzieć ? W końcu chyba każdemu zależy na tym, aby aplikacje były kompatybilne z Windows Vista/7....

No ludzie co jest z wami [!!!]

0

no ale czego oczekujesz? Ten błąd (ja wiem czy to błąd) z atrybutami plików wynika z tego, że w nowych windowsach faAnyFile ma inną wartość niż w starych. Odpowiedź na to jest banalna i tak chyba trzeba robić -

Po prostu trzeba sobie zdefiniować

faWhatever = $FFFFFFFF; //cokolwiek M$ jeszcze wymyśli w przyszłości

i używać jako atrybutów poszukiwania :-)

Co do trzeciego to tak zwracają funkcje systemowe więc Delphi nie ma tu nic do gadania bo i w c++ czy c# zadziała to tak samo (o ile będziesz używał FindFirstFile czy też Delphiowej obudowy FindFirst)

Na 99% problem z ukrytymi to nie wina Delphi tylko windowsa. Zamiast FindFirst i FindNext weź sobie FindFirstFile i FindNextFile i zobacz jak zadziałają, bo jestem pewny, że tak samo

0

Błąd jest po stronie Delphi, nierozsądnym było przyjęcie wartości faAnyFile z tylko konkretnymi flagami zamiast wszystkich. To że w nowszym Delphi zmieniono tę wartość dodając jakieś flagi tylko świadczy, że CodeGear sie jeszcze tego nie nauczyło.

0

Wywołany do tablicy powiem, że nie mam na ten temat za bardzo wiedzy i zdania, bo sam z wyszukiwania
plików korzystam rzadko w swoich aplikacjach. Poza tym używam - póki mam starszy komputer - Windowsa
XP Home SP 2 i od "Wisty" czy siódemki stronie jak się da. Na pewno "majkrosowt" wprowadzając UAC czy
inne pierdołki w "Wiście" przedonrzył i przez to są też problemy z innymi elementami systemu jak choćby to
wyszukiwanie plikó, o ktorym wspomniałeś. Dziwne tylko że najnowsze Delphi sobie z tym nie radzi jakoś ;/

0

Programista NIE MOŻE stronić od nowszych systemów, czy zakładać że najnowszy Windows ABC jest do d_py i dlatego nie będzie poprawiać swojego programu.
Chyba że jest to "programista-egoista", który w życiu jeszcze żadnego programu nie wydał (nawet po kolegach). Przecież publika tak czy siak najnowsze komputery i systemy będzie miała, z czasem coraz częściej.

0

Co do problemu nr 2, to użycie:

FindFirst('*.*', $FFFFFFFF, SearchRec);

jest wyjściem poza zakres.

Natomiast w innym rozwiązaniu piszą, aby zastosować:

FindFirst('*.*', faAnyFile or $00000080, SearchRec);

co w rzeczywistości nie przynosi poprawy...choć mogę się mylić.

Natomiast problem nr 1 rozwiązałem następująco:

private
  procedure ZnajdzPlik(Sciezka: String; Filtry: TStringList);

var
  Form1: TForm1;
  ListaWynikow: TStringList;

procedure TForm1.ZnajdzPlik(Sciezka: String; Filtry: TStringList);
var
 i: SmallInt;
 j: Byte;
 VerifMask: TMask;
 Poprawne: Boolean;
 SR1, SR2: TSearchRec;
begin
 if Sciezka[Length(Sciezka)] <> '\' then Sciezka := Sciezka + '\';

 i := FindFirst(Sciezka + '*.*', faAnyFile, SR1);
 try
  while i = 0 do
    begin
     Application.ProcessMessages;
     if ((SR1.Attr and faDirectory) = 0) and (SR1.Name <> '.') and (SR1.Name <> '..') then
       begin
        for j := 0 to Filtry.Count-1 do
          begin
           VerifMask := TMask.Create(Filtry.Strings[j]);
           Poprawne  := VerifMask.Matches(SR1.Name);
           VerifMask.Free;

           if Poprawne and (ListaWynikow.IndexOf(Sciezka + SR1.Name) = -1) then ListaWynikow.Add(Sciezka + SR1.Name);
           Break;
          end;
       end;

     i := FindNext(SR1);
    end;

  {Szukanie w podfolderach}
  i := FindFirst(Sciezka + '*.*', faDirectory + faHidden, SR2);
  while i = 0 do
    begin
     if ((SR2.Attr and faDirectory) = faDirectory) and (SR2.Name <> '.') and (SR2.Name <> '..') then
       if Pos('\winsxs', Sciezka + SR2.Name) = 0 then ZnajdzPlik(Sciezka + SR2.Name, Filtry);
     i := FindNext(SR2);
    end;

 finally
  FindClose(SR1);
  FindClose(SR2);
 end;
end;

//Wywołanie:
var
 ListaFiltrow: TStringList;
begin
 ListaFiltrow := TStringList.Create;
 ListaWynikow := TStringList.Create;
 ListaFiltrow.Add('*.exe');
 ListaFiltrow.Add('*.dll');

 ZnajdzPlik('C:\', ListaFiltrow);

 ListaFiltrow.Free;
 //--> odczytaj listę wyników z 
 //ListaWynikow

 ListaWynikow.Free;
end;

Szczególnie proszę zwrócić uwagę na:

i := FindFirst(Sciezka + '*.*', faDirectory + faHidden, SR2);

W takiej modyfikacji, zarówno pliki jak i foldery ukryte są znajdywane (szczególnie w Windows 7 dotyczy to folderu: C:\Users<uzytkownik>\AppData\ ).

Dalej nie rozumiem natomiast co ma wspólnego aplikacja 32-bitowa na systemie 32-bitowym z funkcjami:

Wow64DisableWow64FsRedirection
Wow64RevertWow64FsRedirection

i czy rzeczywiście te funkcje trzeba wywołać na systemie 64-bitowym.
Jeśli tak to jak ? bo przecież nie są to znane funkcje.

0
Azarien napisał(a)

Programista NIE MOŻE stronić od nowszych systemów, czy zakładać że najnowszy Windows ABC jest do d_py i dlatego nie będzie poprawiać swojego programu.
Chyba że jest to "programista-egoista", który w życiu jeszcze żadnego programu nie wydał (nawet po kolegach). Przecież publika tak czy siak najnowsze komputery i systemy będzie miała, z czasem coraz częściej.

Azarien, po części masz rację. Jeśli działasz w firmie lub masz fundusze. Postaw się jednak w mojej (i pewnie wielu innych programistów) sytuacji: człowiek pisze w Delphi 3-7, na starym komputerze. Wychodzi nowy system operacyjny i co? To znaczy że mam płacić XXX polskich złotych, za system + najprawdopodobniej nowy sprzęt, bo przecież pod Duronem 800 Mhz NOWY system nie pójdzie.

Druga sprawa, co z kompatybilnością wstecz? Może od razu porzucić wszystko poniżej NOWY system i skupić się tylko na nim. A jeśli nie, to znaczy że musze posiadać u siebie X-systemów tylko po to aby przed opublikowaniem aplikacji przetestować czy się uruchomi na każdym z nich. A jak się nie uruchomi? Zawsze łatwo powiedzieć 'programista-egoista'.

0

Niestety ale tak już jest... piszesz program dla ludzi, musisz inwestować w jego rozwój. A więc musisz testować na równych systemach i mieć do tego odpowiedni sprzęt.
Jeśli temu nie podołasz, Twoja aplikacja prędzej czy później odejdzie i dołączy do aplikacji Abandonware.

0

Opi, jak mam to rozumieć? Posiadasz jednocześnie Windows 98, 2000, XP, Vista oraz 7, czy masz od tego ludzi (mam na myśli testowanie na różnych platformach)? Pytam, bo piszę sam programy, wiec na pierwszy luksus mnie nie stać, a i nie znam nikogo chętnego do drugiej opcji.

0

Testuję oprogramowanie na Windows XP/7 + Beta testerzy + EurekaLog

0

Widzisz.. jeśli ktoś pisze programy typu Freeware (czyli bez żadnego zysku) i jego programy nie mają odpowiedniego poziomu popularności (betatesterzy), bo być może są zbyt słabe lub słabo medialnie promowane, to nie będzie kupować kilku systemów operacyjnych (+ sprzętu który będzie w stanie je obsłużyć). Rozumiem Wasz tok rozumowania, ale to nie powód aby nazywać kogoś innego 'programistą-egoistą który nigdy programu nie napisał'.

Off-top: Tak samo mnie krew zalewa gdy widzę rodziców kupującym dzieciakom super-najnowsze komputery, a ja na swój pierwszy dorabiałem po szkole i kupiłem za własne pieniądze starego 486DX/2 z pamięcią SIMM. I wcale nie było łatwiej programować, niż teraz z Internetem, wirtualnymi maszynami (VMware itp) i całą listą uniwersalnych komponentów, a mimo to się pisało - często dobre programy. Eh, starzeję się..

0
stg napisał(a)

Widzisz.. jeśli ktoś pisze programy typu Freeware (czyli bez żadnego zysku) i jego programy nie mają odpowiedniego poziomu popularności (betatesterzy), bo być może są zbyt słabe lub słabo medialnie promowane, to nie będzie kupować kilku systemów operacyjnych

Microsoft ostatnio wypuszcza tyle wersji beta i półrocznych triali, że da się mieć darmowego Windowsa praktycznie ciągiem.
Poza tym, jeśli jest się jedynym odbiorcą własnych programów, należy przemyśleć strategię ;-)

Off-top: Tak samo mnie krew zalewa gdy widzę rodziców kupującym dzieciakom super-najnowsze komputery, a ja na swój pierwszy dorabiałem po szkole i kupiłem za własne pieniądze starego 486DX/2 z pamięcią SIMM.

Tak, starzejesz się. Jako młody powinieneś się zachwycać i zbierać na Core i7. Jak trochę starszy doszedłbyś do wniosku że szkoda kasy i na razie nie potrzebujesz.

I wcale nie było łatwiej programować, niż teraz z Internetem, wirtualnymi maszynami (VMware itp) i całą listą uniwersalnych komponentów, a mimo to się pisało - często dobre programy.

Nie bardzo rozumiem, dlaczego zakładasz że teraz powinno być trudniej.. pod wieloma względami to teraz jest łatwiej.

0
  1. No tak, Intel pewnie też wypuszcza wersje beta i półroczne triale na Core 2 Duo oraz na inne procesory które podołają coraz to nowszym systemom. A pamięci RAM same się mnożą tylko trzeba je łączyć w pary: samiec z samicą. Beta - ile razy było tak że na wersji beta program nie działał, a na oficjalnej już tak (lub odwrotnie)? Trial się kiedyś kończy, jeśli sprawdzę teraz, a za rok zaktualizuję program do nowszej wersji, to oczywiście znowu mam instalować triala Windowsa aby sprawdzić czy chodzi? Właściwie po co kupować jakiekolwiek oprogramowanie, skoro zawsze można siedzieć na wersjach beta czy trialach?

  2. Idąc Twoim tokiem rozumowania człowiek nigdy nic nie kupi, bo zawsze za jakiś czas będzie można kupić coś lepszego za tą samą cenę, a gdy kupi teraz to przecież za rok to będzie złom, więc się nie opłaca.

  3. Przeczytaj jeszcze raz co napisałem.

0

idąc Twoim tokiem rozumowania, należy nadal pisać pod 486 i Windows 95, twierdząc że to są najlepsze komputery a wszystko potem to sam szit.
Nie piszę, by się rzucać na wszystkie nowości, ale by nie stronić od nowości - wystrzegać się reakcji typu "nie stać mnie to dorabiam ideologię".

0

Hej, masz rację! Jeszcze jutro lecę do sklepu kupić najszybszy procek, najlepszą kartę graficzną i najbardziej pojemny dysk twardy, a jak mi kasy nie starczy to wezmę na kredyt - co z tego że odsetki 16%, przecież najważniejsze że będę mieć super wypasiony sprzęt którego mi pozazdroszczą koledzy z podwórka i na którym Windows 7 będzie hulał, że ho! Gratuluję dobrze płatnej pracy lub bogatych rodziców, naprawdę!

0

Wracam do tego tematu, gdyż problem z szukaniem ukrytych plików i folderów rozwiązałem stosując po prostu faAnyFile.

Natomiast jest kolejny problem z tzw. folderami-linkami.
Podczas szukania, funkcja FindNext zapętla się na folderze, który jest w systemie linkiem do wirtualnego folderu. Następuje kolejno wchodzenie do tego samego folderu:

Pierwszy obieg FindNext:
C:\ProgramData\Application Data\

Drugi:
C:\ProgramData\Application Data\Application Data\

Kolejny:
C:\ProgramData\Application Data\Application Data\Application Data\

itd.
C:\ProgramData\Application Data\Application Data\Application Data\Application Data\

Próbowałem wykluczyć według specyfikacji skróty faSymLink, ale to nie pomaga:

faAnyFile - faSymLink

Takich folderów jest kilka.

Np.: 
C:\Documents and Settings 
jest skrótem do wirtualnego folderu
C:\Users
(lub odwrotnie)

I co radzicie tu zrobić ?
Funkcja FindNext po prostu zapętla się na tych folderach i nie ma tego jak wykluczyć poprzez faSymLink.

Dodam, że w dokumentacji Microsoftu na stronce http://msdn.microsoft.com/en-us/library/ee332330%28VS.85%29.aspx
jest podane coś takiego

FILE_ATTRIBUTE_REPARSE_POINT 1024 0x0400 A file or directory that has an associated reparse point, or a file that is a symbolic link.

Czy więc faSymLink jest równy powyższemu $00000400 ?
Wychodzi, że nie, gdyż faSymLink = $00000040.

Kto rozjaśni mi ten problem?

0

Wracam do tego tematu, gdyż problem z szukaniem ukrytych plików i folderów rozwiązałem stosując po prostu faAnyFile.
Kiedy właśnie wątek dotyczył tego, że faAnyFile jest błędne i nie znajduje niektórych plików.

Czy więc faSymLink jest równy powyższemu $00000400 ?
Nie wiem, ale co ci szkodzi wykonać parę testów, i zobaczyć które flagi są ustawione dla tych katalogów...

0

Czy więc faSymLink jest równy powyższemu $00000400 ?
Nie wiem, ale co ci szkodzi wykonać parę testów, i zobaczyć które flagi są ustawione dla tych katalogów...</quote>

Dlatego, że u mnie ten problem nie występuje. Prawdopodobnie na 64-bit systemach Vista/7 tylko. Jak na razie nie mam jak sprawdzić.

Na innej z kolei stronie
http://docwiki.embarcadero.com/VCL/ja/SysUtils.faSymLink
w nowym Delphi 2010 kompatybilnym z Windows Vista/7 faSymLink ma już wartość zmienioną z $00000040 na $00000400, czyli na taką jaka w dokumentacji Microsoftu.

Wychodzi więc na to, że w starszym Delphi, faSymLink ma wartość niekompatybilną z systemami Vista/7 i dopiero D2010 wprowadza poprawkę.

Czy więc pozostaje zrobienie takiego wybryku ?

const
 faAllFile: Word = $000001FF
 faLinkFile: Word = $00000400;
begin
 FindFirst(Folder, Maska, faAllFile - faLinkFile, TSearchRec);
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1