CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Atrybuty katalogu

Atrybuty katalogu

dział ogólny

Atrybuty katalogu

Nowy postprzez sebaskow » poniedziałek, 9 kwietnia 2012, 21:52

Witam.

Proszę o informację w jaki sposób mogę zmienić programowo atrybuty folderu na systemowe i/lub ukryte. ?


Pozdrawiam.
Avatar użytkownika
sebaskow
Intelektryk
Intelektryk
 
Posty: 135
Dołączył(a): wtorek, 3 maja 2011, 08:30
Lokalizacja: Katowice
Podziękował : 10
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: C++ Builder XE7
Gadu Gadu: 0
    Windows XPChrome

Re: Atrybuty katalogu

Nowy postprzez polymorphism » poniedziałek, 9 kwietnia 2012, 21:56

SetFileAttributes
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: Atrybuty katalogu

Nowy postprzez Cyfrowy Baron » wtorek, 10 kwietnia 2012, 15:53

polymorphism napisał(a):SetFileAttributes


Nie tak, lecz FileSetAttr:

dla plików:
KOD cpp:     UKRYJ  
FileSetAttr("nazwa pliku.roz", faReadOnly);

KOD cpp:     UKRYJ  
FileSetAttr("nazwa pliku.roz", faReadOnly | faHidden); // atrybuty tylko do odczytu i ukryty


Dla folderów jest identycznie, podaje się po prostu nazwę folderu. Istotne jest jednak by zawsze podawać pełną ścieżkę dostępu do pliku lub katalogu, a jeżeli jest to plik lub katalog w katalogu aplikacji to podaje ścieżkę bezwzględną względem programu.

Podany sposób się sprawdzajednak przed zmianą atrybutu pliku, dobrze jest odczytać atrybut jaki ona aktualnie posiada i zmieniać go lub pozostawić bez zmian a dodać nowy, do realizacji tego zadania najlepiej nadają się komponenty typu TCheckBox, będziemy potrzebowali cztery tego typu obiekty, jak cztery rodzaje atrybutów, posłużymy się również dwoma przyciskami typu TButton z których jeden będzie odczytywał atrybuty pliku, a drugi będzie je zmieniał w zależności od ustawień obiektów TCheckBox, stworzymy również dwie funkcje jedną odczytującą atrybuty pliku i ustawiającą odpowiednio obiekty TCheckBox i drugą funkcję zmieniającą atrybuty pliku w zależności od ustawień obiektów TCheckBox:

KOD cpp:     UKRYJ  
//--------------------------------
void __fastcall TForm1::ReadAttrib(String FileName)
{
 int attrib = FileGetAttr(FileName);
 if(attrib & faArchive)  CheckBox1->Checked = true; // archiwalny
 if(attrib & faReadOnly) CheckBox2->Checked = true; // tylko do odczytu
 if(attrib & faHidden)   CheckBox3->Checked = true; // ukryty
 if(attrib & faSysFile)  CheckBox4->Checked = true; // systemowy
}
//--------------------------------
void __fastcall TForm1::ChangeAttrib(String FileName)
{
 int i1 = 0, i2 = 0, i3 = 0, i4 = 0;
 if(CheckBox1->Checked) i1 = faArchive;
 if(CheckBox2->Checked) i2 = faReadOnly;
 if(CheckBox3->Checked) i3 = faHidden;
 if(CheckBox4->Checked) i4 = faSysFile;

 FileSetAttr(FileName, i1 | i2 | i3 | i4);
}
//--------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  ReadAttrib("c:\\temp");
}
//--------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  ChangeAttrib("c:\\temp");
}
//--------------------------------


Ścieżkę bezwzględną względem programu można podać tak:

KOD cpp:     UKRYJ  
 String fPath = ExtractFilePath( ParamStr( 0 ) );
 
ChangeAttrib(fPath + "podkatalog");


Atrybuty folderów i plików kasuje się przekazując funkcji FileSetAttr jako drugi argument wartość NULL.

KOD cpp:     UKRYJ  
FileSetAttr("c:\\katalog", NULL);
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: Atrybuty katalogu

Nowy postprzez polymorphism » wtorek, 10 kwietnia 2012, 17:07

Nie tak (...)

Oj, tak -> link
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: Atrybuty katalogu

Nowy postprzez Cyfrowy Baron » wtorek, 10 kwietnia 2012, 18:26

Fakt jest, tylko w pomocy nic o niej nie ma, a ja nigdy jej nie potrzebowałem. Poza tym od razu założyłem, że skoro Ty ją podałeś to ta funkcja pochodzi z bibliotek VC++, gdyż tego środowiska używasz i w C++Builder na pewno jej nie ma. :?



Ta funkcja ma większe możliwości niż podana przeze mnie w ostatnim poście.

Przykład użycia polegający na dodaniu nowego atrybutu (ukryty) bez zmiany już istniejących atrybutów:

KOD cpp:     UKRYJ  
 wchar_t *pFolder = L"c:\\temp";
 DWORD dwAttrs = GetFileAttributes( pFolder );
 if( dwAttrs == INVALID_FILE_ATTRIBUTES ) return;
 SetFileAttributes( pFolder, dwAttrs | FILE_ATTRIBUTE_HIDDEN );


Przykład usunięcia wszystkich atrybutów:

KOD cpp:     UKRYJ  
 wchar_t *pFolder = L"c:\\temp";

 SetFileAttributes( pFolder, FILE_ATTRIBUTE_NORMAL );


Przykład usunięcia tylko jednego wybranego atrybutu z zachowaniem pozostałych:

KOD cpp:     UKRYJ  
 wchar_t *pFolder = L"c:\\temp";
 DWORD dwAttrs = GetFileAttributes( pFolder );
 if( dwAttrs == INVALID_FILE_ATTRIBUTES ) return;
 SetFileAttributes( pFolder, dwAttrs - FILE_ATTRIBUTE_HIDDEN );


Analogicznie jeżeli plik lub katalog ma więcej niż dwa atrybuty można usunąć dwa pozostawiając pozostałe:

KOD cpp:     UKRYJ  
SetFileAttributes( pFolder, dwAttrs - FILE_ATTRIBUTE_HIDDEN - FILE_ATTRIBUTE_READONLY );


Zastąpienie wszystkich atrybutów nowymi nastąpi zawsze jeżeli nie odczytasz atrybutów katalogu:

KOD cpp:     UKRYJ  
 wchar_t *pFolder = L"c:\\temp";

 SetFileAttributes( pFolder, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY  );


Poza standardowymi atrybutami:

  • FILE_ATTRIBUTE_ARCHIVE
  • FILE_ATTRIBUTE_HIDDEN
  • FILE_ATTRIBUTE_NORMAL
  • FILE_ATTRIBUTE_READONLY
  • FILE_ATTRIBUTE_SYSTEM

Można też sterować atrybutami zaawansowanymi (Win XP i nowsze):

  • FILE_ATTRIBUTE_COMPRESSED
  • FILE_ATTRIBUTE_ENCRYPTED
  • FILE_ATTRIBUTE_REPARSE_POINT
  • FILE_ATTRIBUTE_SPARSE_FILE
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: Atrybuty katalogu

Nowy postprzez polymorphism » wtorek, 10 kwietnia 2012, 19:14

Przykład usunięcia tylko jednego wybranego atrybutu z zachowaniem pozostałych:
KOD cpp:     UKRYJ  
(...) dwAttrs - FILE_ATTRIBUTE_HIDDEN

Błąd, tak powinno być:
KOD cpp:     UKRYJ  
(...) dwAttrs & ~FILE_ATTRIBUTE_HIDDEN


wtedy zamiast:
KOD cpp:     UKRYJ  
dwAttrs - FILE_ATTRIBUTE_HIDDEN - FILE_ATTRIBUTE_READONLY

tak:
KOD cpp:     UKRYJ  
dwAttrs & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY)
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: Atrybuty katalogu

Nowy postprzez Cyfrowy Baron » wtorek, 10 kwietnia 2012, 19:40

polymorphism napisał(a):Błąd, tak powinno być:
KOD cpp:     UKRYJ  
(...) dwAttrs & ~FILE_ATTRIBUTE_HIDDEN


Też działa (tam jest tylda nie minus), ale podany przeze mnie sposób również działa bez zarzutu, testowałem w różnych konfiguracjach i zawsze usuwany jest wybrany atrybut, atrybuty. Nie może więc to być błąd.
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: Atrybuty katalogu

Nowy postprzez polymorphism » wtorek, 10 kwietnia 2012, 21:04

(...) ale podany przeze mnie sposób również działa bez zarzutu

Niestety nie. Jak by tak było, to ten kod:
KOD cpp:     UKRYJ  
DWORD dwAttrs = FILE_ATTRIBUTE_READONLY - FILE_ATTRIBUTE_HIDDEN;

if(dwAttrs == FILE_ATTRIBUTE_READONLY)
{
        cout << "ok\n";
}
 

powinien wyświetlić "ok". Z oczywistych względów tego nie zrobi. Twój kod będzie działać poprawnie tylko wtedy, gdy będziesz zerować bity, które są ustawione, w przeciwnym wypadku zmienisz stan innych bitów, a to już jest bład.
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: Atrybuty katalogu

Nowy postprzez Cyfrowy Baron » środa, 11 kwietnia 2012, 05:25

A jednak działa, gdyż po użyciu kodu:

KOD cpp:     UKRYJ  
SetFileAttributes( pFolder, dwAttrs - FILE_ATTRIBUTE_HIDDEN - FILE_ATTRIBUTE_READONLY );


i sprawdzeniu w Exploratorze Windows i Total Commanderze znikają atrybuty ukryty i tylko do odczytu a pozostałe zostają.

Twój kod niczego nie zmienia, wszak:

KOD cpp:     UKRYJ  
DWORD dwAttrs = FILE_ATTRIBUTE_READONLY - FILE_ATTRIBUTE_HIDDEN;


zmienna dwAttrs w ten sposób nie przyjmuje żadnych atrybutów, gdyż nie nadajesz jej żadnych atrybutów, lecz od razu wykonujesz odejmowanie jednego atrybutu od drugiego. Większy sens miałby taki kod:

KOD cpp:     UKRYJ  
 DWORD dwAttrs = GetFileAttributes( pFolder );

DWORD dwNewAttrs = dwAttrs - FILE_ATTRIBUTE_READONLY;

if(dwNewAttrs & FILE_ATTRIBUTE_READONLY)
{
        cout << "ok\n";
}


Sam popełniłeś błąd gdyż sprawdzanie jaki atrybut zawiera zmienna w warunku powinno wyglądać tak:

KOD cpp:     UKRYJ  
if( dwNewAttrs & FILE_ATTRIBUTE_READONLY )


Sprawdziłem taki kod:

KOD cpp:     UKRYJ  
 DWORD dwAttrs = FILE_ATTRIBUTE_HIDDEN + FILE_ATTRIBUTE_READONLY;
 dwAttrs = dwAttrs - FILE_ATTRIBUTE_HIDDEN;


 if( dwAttrs & FILE_ATTRIBUTE_READONLY ) ShowMessage("Tylko do odczytu");
 else ShowMessage("Brak: Tylko do odczytu");

 if( dwAttrs & FILE_ATTRIBUTE_HIDDEN )   ShowMessage("Ukryty");
 else ShowMessage("Brak: Ukryty");


i Jak najbardziej dział. Sprawdź to sam.



ten kod:

KOD cpp:     UKRYJ  
DWORD dwAttrs = FILE_ATTRIBUTE_READONLY - FILE_ATTRIBUTE_HIDDEN;


Nie ma większego sensu, gdyż co właściwie to ma robić? Przypisać zmiennej atrybut tylko do odczytu jednocześnie odejmując atrybut ukryty, którego ta zmienna nie przyjmuje?
Poza tym jeżeli użyjesz do tego kod warunku jak podałem, to okaże się, że zmienna przyjęła obydwa atrybuty.
Jeżeli jednak pójdę Twoim tropem i dla katalogu, który ma atrybuty zarówno Tylko do odczytu i Ukryty, użyję takiego kodu:

KOD cpp:     UKRYJ  
 wchar_t *pFolder = L"c:\\temp";

 DWORD dwAttrs = GetFileAttributes(pFolder) - FILE_ATTRIBUTE_READONLY;

 if(dwAttrs & FILE_ATTRIBUTE_READONLY) ShowMessage("Tylko do odczytu");
 else ShowMessage("Brak: Tylko do odczytu");

 if(dwAttrs & FILE_ATTRIBUTE_HIDDEN)   ShowMessage("Ukryty");
 else ShowMessage("Brak: Ukryty");


to otrzymam pozytywny wynik, gdyż zmienna będzie miała atrybut Ukryty, ale nie będzie miała atrybutu Tylko do odczytu.
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: Atrybuty katalogu

Nowy postprzez polymorphism » środa, 11 kwietnia 2012, 10:17

Twój kod niczego nie zmienia, wszak: (...) zmienna dwAttrs w ten sposób nie przyjmuje żadnych atrybutów,

No jak nie? Według Twojego sposobu usuwania atrybutu, w dwAttrs powinien zostać jedynie atrybut FILE_ATTRIBUTE_READONLY. Dlatego w warunku dałem porównanie a nie iloczyn logiczny. Ten przykład miał Ci uzmysłowić błąd w myśleniu.

Jeżeli jednak pójdę Twoim tropem i dla katalogu, który ma atrybuty zarówno Tylko do odczytu i Ukryty, użyję takiego kodu: (...) to otrzymam pozytywny wynik.

No właśnie. Teraz użyj tego kodu na katalogu/pliku, który nie ma atrybutu FILE_ATTRIBUTE_READONLY, tylko sprawdź w debuggerze, jakie bity ma ustawione przed operacją zerowania, a jakie po - zrozumiesz, o co mi chodzi ;)
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: Atrybuty katalogu

Nowy postprzez Cyfrowy Baron » środa, 11 kwietnia 2012, 15:25

polymorphism napisał(a):No jak nie? Według Twojego sposobu usuwania atrybutu, w dwAttrs powinien zostać jedynie atrybut FILE_ATTRIBUTE_READONLY.


Wcale nie, gdyż nie nadałeś tego atrybutu plikowi, więc nie może go mieć. Już to wyjaśniłem wcześniej.

polymorphism napisał(a):Teraz użyj tego kodu na katalogu/pliku, który nie ma atrybutu FILE_ATTRIBUTE_READONLY,


Takiej kombinacji nie testowałem i rzeczywiście daje to negatywny wynik. Swoją drogą to mnie od początku intrygowało, dlaczego odejmowanie wartości od zmiennej daje takie efekty, gdyż zmienna DWORD może przechowywać tylko pojedynczą wartość liczbową, więc podejrzewałem, że błąd może w pewnej sytuacji wystąpić, jednakże zakładałem również, że twórca tej funkcji to przewidział i tak ustawił zakres flag, że to powinno zawsze działać dobrze.

Rzeczywiście to odejmowanie się nie sprawdza, a liczyłem, że można to w ten sposób załatwić.
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 4 gości