Słuchajcie, jak zmienić atrybuty folderu z tylko do odczytu na normalne i odwrotnie, jakby się dało to razem ze wszystkimi podfolderami?
Zmiana atrybutów folderu jest taka sama jak plików. A co za tym idzie, wystarczy warunkowo sprawdzać, czy obiekt jest folderem i zmieniać mu atrybut.
A jak sprawdzić? Po prostu:
if DirectoryExists(sciezka_do_folderu) then
...
Tym poleceniem nie sprawdzasz czy to jest folder...
Do tego celu używasz klasy TSearchRec.
A mógłbyś jakoś podpowiedzieć jak tego użyć?
Rozumiem, że później mam zrobić coś takiego:
SetFileAttributes('C;\katalog\, FILE_ATTRIBUTE_NORMAL);
Pogoogluj za przykładami, pierwszy lepszy link: http://www.delphibasics.co.uk/RTL.asp?Name=FileSetAttr
No niestety dużo googlowałem, ale niestety nie działa. Na ten przykład, miało wyłączać tryb tylko do odczytu, ale nie działa:
procedure jakas_tam;
var
searchResult : TSearchRec;
folderpath: string;
attrs : integer;
begin
folderpath := 'C:\Folder';
setcurrentdir(folderpath);
if FindFirst('*', faDirectory, searchResult) = 0 then
begin
repeat
if (searchResult.attr and faDirectory) = faDirectory then
begin
attrs := FileGetAttr(folderpath + '\' + searchresult.name);
if attrs and faReadOnly > 0 then
begin
if (Searchresult.Name[1] <> '.') then
FileSetAttr(folderpath + '\' + searchresult.Name, 0);
end;
end;
until FindNext(searchResult) <> 0;
FindClose(searchResult);
end;
FileSetAttr(folderpath, 0);
end;
Przyznam się, że z korzystaniem z wyszukiwania plików miałem zawsze problemy by to napisać samodzielnie, a jedyny użyty przeze mnie dynamicznie moduł, jaki działa jak należy pobrałem stąd: http://www.torry.net/vcl/filedrv/search/wdfindf.zip polecam nim wyszukać podkatalogi (można ustawić aby tylko je wyszukiwał w danej ścieżce). Następnie dla zwróconej listy ścieżek do katalogów, wykonać sprawdzanie i w zależności od posiadanych już atrybutów ustawić nowe atrybuty, bo tak chyba - o ile dobrze zrozumiałem - ma działać kod wedlug Ciebie.
No tak właśnie chciałem. Spróbuję.
Niestety mam problem z zainstalowaniem tego komponentu dla Delphi 2009. Zainstalowałem dla Delphi 7, ale niestety nie działa mi wywołanie funkcji:
var
strDirs: TStringList;
begin
FindFile1.FindSubDirectory(strDirs, Edit1.Text);
...
Niestety wyrzuca mi w tej funkcji "Undeclared identifier", konkretnie w "FindSubDirectory".
Nie wiem z czym masz problem. Jak masz undeclared indefider to za pewne używasz metody, której kompilator nie zna. Ja użyłem tego modułu findfile.pas do tej pory tylko w jednym programie i zrobiłem to dynamicznie. Czyli wrzuciłem moduł do kataloigu projektu i dodałem go do sekcji uses, a wyszukiwanie robiłem w wątku (FRecurse to zmienna ustawiana przez konstruktor wątku 0 jest ona typu boolean oczywiście) tak jak poniżej:
var
FF : TFindFile;
begin
with MainForm do
begin
try
FindedSL := TStringList.Create;
FF := TFindFile.Create(MainForm);
FF.Recurse := FRecurse;
FF.Directory := DirLabel.Caption;
FF.Filter := '*.ico';
FF.Execute;
finally
FindedSL.Assign(FF.Files);
FF.Free;
end;
//...
Poza tym przecież w źródle komponentu widać wyraźnie, że można własnością ustawić jakiego typu pliki czy katalogi ma wyszukiwać:
type
TAttrOption = (ffReadOnly, ffHidden, ffSystem, ffVolumeID, ffDirectory, ffArchive);
TAttrOptions = set of TAttrOption;
//...
property Attributes: TAttrOptions read FAttribs write FAttribs
//...
Komponent był - jak wcześniej wspomniałem - testowany przeze mnie i się jak dla mnie sprawdził dobrze. A Ty chyba masz problem z jakimiś elementarnymi podstawami jak używanie komponentów dynamicznie, a żeby to ogarnąć powinieneś najpierw chyba poznać podstawy języka Delphi, a dopiero później brać się za bardziej zaawansowane programy, które coś wyszukują ;/
No przecież napisałem, że nie udało mi się zainstalować, ale przełożyłem sobie te funkcje do programu, czyli podpiąłem plik, tak jak piszesz, no bo przecież jak inaczej i mi wyszukuje foldery tak jak chcę, tylko mam problem już ze zmianą atrybutów wyszukanych folderów.
FileSetAttr(lista[i], not faReadOnly);
FileSetAttr(lista[i], 0);
Niestety oba sposoby nie działają... A podobno robi się tak samo jak z plikami...
Nie wiem co Ty kombinujesz. Nie masz pojęcia o operacjach logicznych i podstawach. Ja też mam to pojęcia słabe, ale wystarczy zajrzeć do helpa i wiele się wyjaśnia. No ale wiadomo po co szukać i coś samodzielnie pokombinować ;/ Kod:
const
DirName = 'D:\PFT';
var
Attributes : WORD;
begin
Attributes := FileGetAttr(DirName);
if (Attributes and faReadOnly = faReadOnly)
and (Attributes and faDirectory = faDirectory) then
begin
FileSetAttr(DirName, Attributes and not faReadOnly);
ShowMessage('Zmieniono atrybuty dla: ' + DirName);
end;
end;
Przed jego wykonaniem powyższego kodu ustawiamy atrybuty i mamy:
D:\>attrib PFT +a +r
D:\>attrib PFT
A R D:\PFT
Po wykonaniu kodu mamy to co poniżej czyli wszystko działa:
D:\>attrib PFT
A D:\PFT
Testowane pod Windows 7 Ultimate 64 bit PL. Do zrzucenia zawartości komend użyłem najnowszego i dostepnego FileManagera FAR, bo kopiowanie z pod ConEmu lub gołego cmd.exe mi nie wychodziło.
delphi_maker napisał(a)
FileSetAttr(lista[i], not faReadOnly);
To jest totalnie bez sensu. Przecież not faReadOnly = $FFFFFFFE
Musisz odczytać atrybuty do jakiejś zmiennej, w tej zmiennej wyzerować atrybut faReadOnly i dopiero potem zmienić atrybuty pliku/katalogu.
var attr:Integer;
//...
attr:=FileGetAttr(lista[i]);
attr:=attr and (not faReadOnly);
FileSetAttr(lista[i],attr);
//... albo jedną instrukcją
FileSetAttr(lista[i],FileGetAttr(lista[i]) and (not faReadOnly));
W zasadzie ten temat jest kontynuacją tego: Błąd zapisu plików z pliku zasobów. z tym, że wykryłem, że chodzi właśnie o atrybuty katalogów i założyłem nowy temat.
No więc olesio twoja metoda działa, sam nawet wcześniej sobie zrobiłem sprawdzanie, czy katalog ma atrybut tylko do odczytu, ale niestety jak zmienię atrybuty folderu twoim sposobem i chcę do niego zapisać pliki, tak jak w podanym temacie, to problem występuje dalej, jeśli natomiast zmienię atrybut ręcznie z poziomu Windowsa to wszystko jest ok. Jakaś myśl?
Mój sposób po poprawieniu według moich testów działa, jak należy. Zresztą ustawienie read only dla folderu powoduje tylko ewentualne ostrzeżenie pod Total Comamnderem, że folder jest tylko do odczytu i czy na pewno chcesz go usunąć. Nie wiem jak z innymi programami. Nie wiem też dokladnie czy dla ustawienia atrybutów program ustawiający ma być uruchomiony na prawach Administratora. Nie podałeś jakiego systemu używasz i czy jest na nim włączone UAC. A ja raczej nic więcej w kwesti atrybutów ponad to co napisałem powyżej nie wymyślę. Może ktos inny coś jeszcze Tobie tu doradzi.
Jak sprawdzam pod Total Commanderem, to atrybuty się znoszą, ale żeby udało się zapisać plik, to muszę zmienić atrybuty przez Exploratora Windows. Program uruchamia się z prawami administratora, mam zrobiony plik manifestu, Windows 7 x86 Professional, UAC wyłączone.