Mam pewien problem z dzialaniem funkcji FindFirst na systemie Vista.
Moze ktos z was sie z tym spotkal.
Wyciagnalem katalog dla danych aplikacji w katalogu profilu uzytkownika
i stworzylem w nim podkatalogi i pliki z danymi. Pliki tworza sie ok,
wiec uprawnienia sa. Katalog wyglada tak:
c:\Users\uzytkownik\AppData\Roaming\program\katalog\
Gdzie 'uzytkownik' to nazwa mojego uzytkownika. Katalog 'program' to
katalog dla mnie, ktory utworzylem, a w nim podkatalog 'katalog'. Pliki
sie w srodku stworzyly. Teraz probuje je odczytac z tego katalogu, zeby
wyciagnac ich liste. Robie to mniej wiecej tak:
var
sr:TSearchRec;
FileAttrs:integer;
begin
FileAttrs := faAnyfile; //probowalem tez kombinacji: faReadOnly +
faHidden + faSysFile + faArchive;
if
FindFirst('c:\Users\uzytkownik\AppData\Roaming\program\katalog\*.txt',
FileAttrs, sr) = 0 then begin
...
...
Katalog w Findfirst oczywiscie nie jest na sztywno wpisany, tylko w
zmiennej wyciagnietej wczesniej.
No i wszystko gra na XP, natomiast na viscie ten kawalek programu
przechodzi bez bledow, jednak plikow nie znajduje. Nie rozumiem tego, bo
to samo na XP dziala normalnie. Findfirst po sprawdzeniu funkcja
getlasterror zwraca brak bledow. Po prostu twierdzi, ze jest 0
znalezionych plikow.
Czy ktos sie z tym spotkal i ma jakies wskazowki? Co trzeba na viscie
zrobic, zeby normalnie to zadzialalo?
Z gory dzieki.
--
GAD Zombie
http://gad.art.pl/ (a email dosc podobny ;))
A jak pobierasz ten katalog?
Og�lnie to grzebiesz po katalogach, kt�re Vista przemapowuje i k�amie na
temat ich struktury.
Spr�buj SHGetSpecialFolderLocation z parametrem CSIDL_LOCAL_APPDATA - to
zwraca katalog, kt�ry dzia�a w Vi�cie i XP (sprawdzone).
--
Azarien
Może masz 64-bitową vistę?
<cytat z MSDN>
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.
</cytat>
Wyglada na to że MS znów coś popie@#%#45... Teraz każdy program 32-bit
który uzywa FindFirst bęzie źle działał na systemach 64-bit...
--
Arivald
Nie każdy - zależy na jakich katalogach będzie operował...
--
marfi
Uzywam wlasnie tej funkcji. Napisalem juz, ze ten katalog tworzy mi sie
prawidlowo, tworza mi sie tez w nim pliki zapisywane przez moj program,
wiec i katalog mam zlokalizowany dobrze i uprawnienia do zapisu mam.
Mimo to findfirst nie zwraca mi tam zadnych wynikow...
Nie, sprawdzilem to na 32-bit.
> <cytat z MSDN>
> 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.
> </cytat>
>
> Wyglada na to �e MS zn�w co� popie@#%#45... Teraz ka�dy program 32-bit
> kt�ry uzywa FindFirst b�zie �le dzia�a� na systemach 64-bit...
To dosc ciekawe, moze ma jakis zwiazek. Tu jest napisane o 64-bit
komputerze, a nie systemie, a ja siedze na AMD 64. Chociaz wydaje mi
sie, ze to troche bez sensu, bo system powinien byc tu bardziej istotny.
Tak czy siak sprawdze to.
Moze ktos jeszcze ma jakis inny pomysl?
Sprawdzilem, ale to niestety nie to. Funkcja Findfirst dziala prawidlowo
na innych katalogach.
Sprawdzilem tez gdzie juz nie mozna nic sprawdzic i wyglada mi na to, ze
nie moge odczytac juz nic w katalogu:
c:\Users\UZYTKOWNIK\AppData\*.*
Wszystko, co wewnatrz tego sprawdzam, zawsze zwraca 0 wynikow w Findfirst...
Aha, dla scislosci napisze, ze nie mam pod reka Visty, dostalem takie
zgloszenie od uzytkownika i sprawdzam u siebie na Win Server 2008 (ktory
jest oparty na Viscie i powinno w nim byc to wszystko tak samo jak w
Viscie - problem w kazdym razie jest tu ten sam).
Sprawdziłem na mojej Viscie i W7, i działa normalnie (prosta testowa
aplikacyjka).
Z jakimi uprawnieniami uruchamiasz aplikację? Bo żeby czytać z katalogu
użytkownika trzeba mieć odpowiednie uprawnienia.
Z tego co pamiętam to domyślne konto usługi nie ma dość uprawnień.
--
Arivald
Uruchamiam normalnie, bo to nie jest usluga. Odpalam exeka recznie, a
katalog usera, do ktorego probuje zajrzec, to katalog tego usera, ktory
jest zalogowany.
Jesli by chodzilo o uprawnienia, to bardzo dziwi mnie fakt, ze mam
mozliwosc zapisania pliku w tym katalogu, a nie mam uprawnien do
przejrzenia go funkcja findfirst w jednej aplikacji.
Spróbuj zbudować nową aplikację, tylko z findfist. Jak zadziała
poprawnie, to będziesz wiedział ze to coś innego Ci miesza. Dobudowując
kod kawałek po kawałku może znajdziesz źródło problemu.
BTW: VirtualPC player jest darmowy, a obraz z Vistą (darmowy i legalny!)
można ściągnąć z MS. Ta Vista to obraz do celów testowych, będzie
działał przez miesiąc. Nie pamiętam teraz niestety urla, ja obraz już od
dawna trzymam na dysku. Pogoogluj za "Vista VHD Test Drive".
Druga opcja to jeśli ściągnąłeś instalkę Win7 RC, to jeszcze przez pół
roku będzie działać normalnie i legalnie na VirtualPC.
Dla mnie takie wirtuale to najlepsza metoda na testowanie.
--
Arivald
Wlasnie tak to sprawdzalem - pusta aplikacja i tylko ta jedna rzecz w
niej, od razu efekt opisywany wczesniej..
> BTW: VirtualPC player jest darmowy, a obraz z Vistďż˝ (darmowy i legalny!)
> mo�na �ci�gn�� z MS. Ta Vista to obraz do cel�w testowych, b�dzie
> dzia�a� przez miesi�c. Nie pami�tam teraz niestety urla, ja obraz ju� od
> dawna trzymam na dysku. Pogoogluj za "Vista VHD Test Drive".
>
> Druga opcja to je�li �ci�gn��e� instalk� Win7 RC, to jeszcze przez p�
> roku b�dzie dzia�a� normalnie i legalnie na VirtualPC.
>
> Dla mnie takie wirtuale to najlepsza metoda na testowanie.
Wiem, testuje na VMWare, ale akurat mam na nim tylko w2008 server.
Faktem jest jednak, ze o tym problemie dowiedzialem sie od uzytkownika
programu, ktory ma Viste, wiec problem jest identyczny na obu systemach.
Zapewne jak go rozwiaze na 2008, to na Viscie tez ruszy.
> Witam
>
> Mam pewien problem z dzialaniem funkcji FindFirst na systemie Vista. Moze
> ktos z was sie z tym spotkal.
> Wyciagnalem katalog dla danych aplikacji w katalogu profilu uzytkownika i
> stworzylem w nim podkatalogi i pliki z danymi. Pliki tworza sie ok, wiec
> uprawnienia sa. Katalog wyglada tak:
> c:\Users\uzytkownik\AppData\Roaming\program\katalog\
>
> Gdzie 'uzytkownik' to nazwa mojego uzytkownika. Katalog 'program' to
> katalog dla mnie, ktory utworzylem, a w nim podkatalog 'katalog'. Pliki
> sie w srodku stworzyly. Teraz probuje je odczytac z tego katalogu, zeby
> wyciagnac ich liste. Robie to mniej wiecej tak:
>
<ciach>
Z pewn� tak� nie�mia�o�ci� pozwol� sobie na udzielenie wskaz�wki.
Po ukazaniu si� Visty te� zauwa�ono ten problem w moim programie.
�cie�k� do folderu przekazywa�em jako argument funkcji.
np: 'c:\Users\uzytkownik\AppData\Roaming\program\katalog\
Problem stanowi� ten ostatni uko�nik. Prosz� pokombinowa�, przyjrze�
si�, jak si� uk�adaj� te uko�niki. Tu dokonywa�em zmian w swoim programie.
Szczeg��w nie pomn�, ale problem zosta� usuni�ty i jedn� funkcj�
obudowuj�c�
FindFirst listowa�em poprawnie foldery we wszystkich Win<=Vista.
Pozdrawiam
WS
> Szczeg��w nie pomn�, ale problem zosta� usuni�ty i jedn� funkcj�
> obudowuj�c�
> FindFirst listowa�em poprawnie foldery we wszystkich Win<=Vista.
Dzieki, ale zwracam uwage na sciezke, ktora ja podalem w przykladzie i,
z ktorego korzystam:
'c:\Users\uzytkownik\AppData\Roaming\program\katalog\*.txt'
Czyli nie podaje samego katalogu, a pelna sciezke wraz z maska na koncu
(*.txt), wiec tu nie ma czego usuwac, bo ostatni backslash musi byc
przed maska.
A czy sama scieżka 'c:\Users\uzytkownik\AppData\Roaming\*.*' zadziała?
bo może ustawienia katalogów "program" i "katalog" coś utrudniają?
Ja dla testu uzyłem
'c:\Users\uzytkownik\AppData\Roaming\*.*'
'c:\Users\uzytkownik\AppData\Roaming\Microsoft\*.*'
'c:\Users\uzytkownik\AppData\Roaming\Microsoft\Identities\*.*'
I zawsze działo normalnie.
--
Arivald
Tak, juz pisalem o tym we wczesniejszym poscie:
> Sprawdzilem tez gdzie juz nie mozna nic sprawdzic i wyglada mi na to,
> ze nie moge odczytac juz nic w katalogu:
> c:\Users\UZYTKOWNIK\AppData\*.*
> Wszystko, co wewnatrz tego sprawdzam, zawsze zwraca 0 wynikow w
> Findfirst...
Czy moglbym Cie prosic o ten testowy program (zrodlo), ktory Ci dziala
prawidlowo? Moze zwyczajnie ja robie cos zle i dlatego nie dziala.
Chetnie porownam z moja wersja. Z gory dziekuje.
Poprawka, uzywam SHGetFolderPath() z parametrem CSIDL_APPDATA.
Ale wyglada na to, ze zwraca to samo, bo dziala ok. Chociaz ciekawy
jestem czemu takie funkcje sa dwie..
OK, juz nie trzeba.
Zdaje sie, ze rozwiazalem problem, aczkolwiek go nie rozumiem.
Wyglada na to, ze w systemie Vista pliki w tych katalogach maja jakies
dodatkowe atrybuty, ktorych nie mam do wyboru nawet w stalych
odpowiadajacych atrybutom. Czyli, dostepne atrybuty mam (z helpa):
faReadOnly $00000001 Read-only files
faHidden $00000002 Hidden files
faSysFile $00000004 System files
faVolumeID $00000008 Volume ID files
faDirectory $00000010 Directory files
faArchive $00000020 Archive files
faAnyFile $0000003F Any file
Czyli max co mozna wybrac to faAnyFile jako suma wszystkich pozostalych.
Sprawdzilem na bezczelnego cos takiego:
FindFirst(maska, $FFFFFFFF, sr) ...
i znalazlo wszystkie pliki. Sprawdzilem wiec im atrybuty i okazalo sie,
ze pliki znalezione w tym katalogu maja atrybuty o wartosci: $00002020,
czyli cos, czego w ogole nie ma w powyzszych stalych i stad mi
filtrowalo wszystkie pliki.
Dlaczego tak? Na razie nie wiem, moze cos znajde w sieci ;). Tak czy
siak dziekuje za pomoc, udalo sie. Chociaz wciaz nie rozumiem do konca... ;)
pozdrawiam porannie
Jeszcze dodam, ze faktycznie we wlasciwosciach pliku widze atrybuty
"AN", kiedy zwykly plik ma tylko "A", wiec pewnie to N = $2000. Moze to
jakis dodatkowy atrybut dla plikow w profilowanych katalogach?
FindFirst z Delphi jest oparte o FindFirstFile z WinAPI.
http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx
A obsługiwane atrybuty są tu:
http://msdn.microsoft.com/en-us/library/ee332330(VS.85).aspx
--
Arivald
--
marfi
Dzieki, wszystko sie wyjasnia.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 0x2000 The file or directory is
not to be indexed by the content indexing service.
To by po czesci potwierdzalo teorie ikarka, ktora opisal w poscie z
27.10.2009 20:23 (o indeksacji - ktora nie jest rozwiazaniem problemu,
tylko obejsciem).
Moze istotnym jest fakt, ze siedze na Delphi5, gdzie atrybuty byly
jednak prostsze, bo jeszcze nikomu sie nie snil Windows Vista :)
Tylko wygl�da na to, �e w Delphi 2010 wcale nie jest du�o lepiej.
Sprawdzi�em wyrywkowo jak wygl�daj� "File attribute constants" dla:
Delphi 2007:
faReadOnly = $00000001 platform;
faHidden = $00000002 platform;
faSysFile = $00000004 platform;
faVolumeID = $00000008 platform deprecated; // not used in Win32
faDirectory = $00000010;
faArchive = $00000020 platform;
faSymLink = $00000040 platform;
faAnyFile = $0000003F;
Delphi 2010:
faReadOnly = $00000001 platform;
faHidden = $00000002 platform;
faSysFile = $00000004 platform;
faVolumeID = $00000008 platform deprecated; // not used in Win32
faDirectory = $00000010;
faArchive = $00000020 platform;
faSymLink = $00000040 platform;
faNormal = $00000080 platform;
faTemporary = $00000100 platform;
faAnyFile = $000001FF;
--
pozdrowienia
Krzysztof Szyszka, X-Files Software
Developer of X-Files Components
Borland/CodeGear/Embarcadero Technology Partner
_________________________________________
Website: http://www.x-files.pl/ E-mail: ne...@x-files.pl
O rany, rzeczywiscie. Bylem pewny, ze w nowszym Delphi bedzie lepiej.
Wyglada na to, ze moj problem moze spotkac teraz kazdego, nawet z
najnowszym Delphi.
faWhatever = $FFFFFFFF; //cokolwiek M$ jeszcze wymy�li w przysz�o�ci
i u�ywa� jako atrybut�w poszukiwania :-)
Tygrys
To nie jest błąd MS. FindFirstFile() / FindNextFile() nie filtrują
danych, zwracają wszystko. To kod Delphi później odfiltrowuje
niepasujące pliki.
A wszystko to z powodu zbyt mocnej optymalizacji... ktoś nie przewidział
że mogą zostać dodane nowe atrybuty. Spragnionym szczegółów zalecam
zapoznanie się z kodem FindFirst() i FindMatchingFile(var F: TSearchRec).
Osobiście skłaniam się do napisanie własnej klasy do wyszukiwań, która
była by wygodniejsza i bezpieczniejsza w użyciu od FindFirst(). Np.
sprawdzanie czy plik pasuje można robić na callbacku lub evencie.
Będzie mi to potrzebne w projekcie, bo sporo importów u mnie używa
FindFirst() do importowania wielu plików na raz.
--
Arivald
Oczywiscie, nikt nie mowi, ze to blad. Po prostu w unicie do Delphi
brakuje odpowiednich stalych, ktore moznaby przekazywac w parametrze do
tej funkcji. Fakt - mozna zdefiniowac je samemu wzorujac sie na stalych
podanych w MSDN i pewnie to zalatwi problem.