
Эксперт
  
Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург
Репутация: 24 Всего: 67
|
| Цитата(kma @ 15.12.2005, 11:33) | | Подскажите, как можно изменять ReadOnly в дочерних файлах и папках |
Вот накорябал один класс, который покамест может только снимать/устанавливать атрибуты (подробности внутри): | Код | /******************************************************************************\ Данный объект покамест позволяет только снимать/устанавливать наборы атрибутов для файлов и каталогов (вместе с подкаталогами). Можно устанавливать маску файлов.
© Created by Ciber SLasH (2005) \******************************************************************************/ //-- Константы кнопок ---------------------------------------------------------- MB_OK = 0x0 MB_OKCANCEL = 0x1; //-- Константы иконок ---------------------------------------------------------- MB_ICONERROR = 0x10; MB_ICONINFORMATION = 0x40; //////////////////////////////////////////////////////////////////////////////// WshShell = WScript.CreateObject("WScript.Shell"); FSO = WScript.CreateObject("Scripting.FileSystemObject");
//////////////////////////////////////////////////////////////////////////////// //==[ FileSystemObj ]=========================================================== //////////////////////////////////////////////////////////////////////////////// /* Объект может создаваться как с параметрами (можно и с одним), так и без. Если он создаётся без параметров, то все необходимые аргументы должны передаваться прямо в его методы.
@property1 — полный путь к файлу (каталогу), может включать маску файлов по шаблону. Пример: "*|(.htm|.js)" @property2 — число итераций, после которого будет выведено сообщение о том, что обработано "itemCount" файлов/каталогов
Остальные свойства являются внутринними, НЕ для использования "из вне". */
function FileSystemObj(path, itemCount) { this.path = path; this.itemCount = itemCount; /* funcData — массив данных методов. Пример данных, метода "SetAttribute": funcData = Array( "SetAttributes" => { path: String — полный путь к файлу (каталогу) fileExt: String — шаблон файлов subFolders: Boolean = false — признак обхода подкаталогов attrs: Array(String) — массив устанавливаемых/сбрасываемых атрибутов jobType: Number — вид задания stepCount: Number = 0 — пройденное количество итераций } ); Пример массива "attrs" для шаблона "-1|2|-4": funcData["SetAttributes"].attrs = Array( 0 => "-1|2|-4", 1 => "-1", 2 => "2", 3 => "-4" ); */ this.funcData = []; this.objName = "FileSystemObj"; // имя объекта (используется при выводе ошибок) this.errors = new Error(); // объект ошибок }
/*-- Внутренний метод рекурсивного обхода каталогов --*/ /* @param1 — имя метода, тело которого выполняется при каждом внутринним проходе */ FileSystemObj.prototype.ScanFolder = function (funcName) { var ErrInfo = this.objName+ "::ScanFolder"; // имя метода (используется при выводе ошибок) var jobData = this.funcData[funcName]; // ссылка на элемента массива с данными метода "funcName" var thisObj = this; // ссылка на текущий объект var currCount = 0; // счётчик проходов
/*- Внутренний трэд рекурсивного обхода каталогов -*/ /* @param1 — полный путь к каталогу */ scanThread(jobData.path); function scanThread(Dir) { var currDir = FSO.GetFolder(Dir); // ссылка на текущий объект-каталог
jobData.path = currDir; // записываем путь к каталогу в массив данных метода "funcName" thisObj[funcName](); // вызываем метод "funcName"
currCount++; // увеличиваем счётчик проходов // Если текущий проход == указанному количеству проходов, после которого нужно вывести сообщение, то... if (currCount % thisObj.itemCount == 0) WshShell.Popup("Обработано объектов: " +currCount+ "\nОбработка продолжается...", 0, "Info [" +ErrInfo+ "::scanThread]", MB_OK | MB_ICONINFORMATION);
var SubDirs = new Enumerator(currDir.SubFolders); // получаем список подкаталогов текущего каталога while (!SubDirs.atEnd()) { // пробег по всем подкаталогам currDir = SubDirs.item(); // новый каталог уровня ниже scanThread(currDir); // снова обходим новый каталог SubDirs.moveNext(); // смещаемся на следующий каталог того же уровня } } }
/*** Метод установки/снятия аттрибутов с файла (каталога) и их списков ***/ /* @param1* — полный путь к файлу/каталогу, чьи атрибуты нужно изменить. Если при создании объекта был указан полный путь к файлу/каталогу, то первый параметр можно опустить, иначе его необходимо указать здесь. Путь к каталогу должен оканчиваться на бэкслэш "\" (прим. в JavaScript бэкслэши должны быть заискейпнуты, т.е. дополняться ещё одни бэкслэшем "\\"). В пути может быть находиться маска файла. Примеры: "J:\\TestFolder\\" — обработать один каталог "J:\\TestFolder\\*" — обработать каталог и все файлы "J:\\TestFolder\\.html|.js" — обработать каталог и все файлы с расширениями HTML и JS
@param2 — признак обхода вложенных каталогов (true/false) по умолчанию: false. Второй параметр может быть опущен, по умолчанию он установлен в false.
@param3* — набор аттрибутов. Он представляет собой строку атрибутов разделённых символом "|". Пример: "-1|2|-4" (снять бит ReadOnly, установить бит Hidden, снять бит System). Доступные значения:
(0) Normal — без атрибутов (1) ReadOnly — только чтение (2) Hidden — скрытый (4) System — системный (8) Volume — метка диска (неизменяемый) (16) Directory — каталог (неизменяемый) (32) Archive — архивный (1024) Alias — ссылка или ярлык (неизменяемый) (2048) Compressed — сжатый файл (неизменяемый)
Сам метод может быть вызван следущими вариантами: SetAttribute(attrs) — в этом случае путь к файлу (каталогу) обязан быть указан либо при создании объекта, либо установкой его свойства "path" SetAttribute(subFolders, attrs) — в этом случае путь к файлу (каталогу) указывается так же, как и в первом варианте SetAttribute(pathAttr, subFolders, attrs) — вызов метода с указанием всех параметров */ FileSystemObj.prototype.SetAttribute = function (pathAttr, subFolders, attrs) { /*- Внутренняя функция проверки на изменение набора атрибутов -*/ /* @param1 Array — массив изменяемых атрибутов. Пример: Array("-1", "2", "-4"); @param2 Number — атрибуты объекта (папки или файла);
Функция возвращает массив тех атрибутов, которые не получилось установить/снять. Массив имеет следующий вид (пример для шаблона "-1|2|-4"): Result = Array( 0 => -1, 1 => 2 ); // означает, что атрибут ReadOnly не удалось снять, а атрибут Hidden не удалось установить. */ function testAttrs(srcAttrs, objAttrs) { var Result = []; for (var i = 1; i < srcAttrs.length; i++) { var numAttr = Number(srcAttrs[i]); if (numAttr < 0) { // если снимаем атрибут if ( !(objAttrs & Math.abs(numAttr)) ) Result.push(numAttr + "\t — попытка снять НЕ установленный атрибут;"); } else // если устанавливаем атрибут if (objAttrs & numAttr) Result.push(numAttr + "\t — попытка установить уже установленный атрибут;"); } return Result; }
var ErrInfo = this.objName+ "::SetAttribute"; // имя метода (используется при выводе ошибок)
if (this.funcData["SetAttribute"] == undefined) { // если данных метода ещё не существует // Соответствует литеральному: [^\"*/:<|>?\\]+ — рег для части пути var pathReg = "[^\"*/:<|>?\\\\]+"; // Рег для расширения файл(а|ов). Пример: "*|(.htm|.js)" var extReg = "\\*|(?:\\." +pathReg+ "\\|?)+"; // Рег для полного пути вместе с возможным расширением файлов var Reg = new RegExp("^[a-zA-Z]:(?:\\\\" +pathReg+ ")+\\\\?(?:" +extReg+ ")?$");
var pathAt = (this.path != undefined) ? this.path : (typeof(pathAttr) == "string") ? pathAttr : undefined; // Если "pathAt" не является путём к каталогу или файлу. Или несоответствующий шаблон расширения if (!Reg.test(pathAt)) { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = ErrInfo + '\n\tНеверно задан путь: "' +pathAt+ '"'; throw this.errors; // вызываем исключение } var typeOfJob, extOfFile; if (pathAt.charAt(pathAt.length-1) == "\\") typeOfJob = 2; // работа с одним каталогом else { Reg = new RegExp(extReg + "$"); // рег для расширения файлов extOfFile = Reg.exec(pathAt); // применяем рег /* Если рег прошёл для расширения и предыдущий символ, перед полученным с помощью рега строки, символ бэкслэша "\" (первый бэкслэш с конца пути), то... */ if (extOfFile != null && pathAt.charAt(pathAt.length - extOfFile.toString().length-1) == '\\') { pathAt = pathAt.replace(extOfFile, ""); // удаляем из пути шаблон расширений typeOfJob = 3; // работа с каталогом и списком файлов определённых расширений } else typeOfJob = 1; // работа с одним файлом } // Определяем, каким параметром пришёл признак обхода каталогов (если вообще пришёл) var subFld = (typeof(pathAttr) == "boolean") ? pathAttr : (typeof(subFolders) == "boolean") ? subFolders : false; // Определяем, каким параметром у нас набор атрибутов var attrReg = /^(-?[0-9]\|?)+$/; // рег для атрибутов var attrValidReg = /^(-?(0|1|2|4|8|16|32|1024|2048)\|?)+$/; // рег для правильных атрибутов var atribs = (attrReg.test(pathAttr)) ? pathAttr : (attrReg.test(subFolders)) ? subFolders : (attrReg.test(attrs)) ? attrs : undefined; // Если НЕ был задан набор атрибутов или атрибуты неправильные if (atribs == undefined || !attrValidReg.test(atribs)) { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = "[" +ErrInfo+ "]" + (atribs == undefined) ? "\n\tНЕ заданы атрибуты !!" : '\n\tНеправильно заданы атрибуты: "' +atribs+ '"'; throw this.errors; // вызываем исключение } //--[ Установка данных метода ]----------------------------------------- this.funcData["SetAttribute"] = {}; this.funcData["SetAttribute"].path = pathAt; this.funcData["SetAttribute"].fileExt = (extOfFile != undefined) ? extOfFile.toString().toUpperCase() : undefined; this.funcData["SetAttribute"].subFolders = subFld; this.funcData["SetAttribute"].attrs = [atribs].concat(atribs.split("|")); this.funcData["SetAttribute"].jobType = typeOfJob; this.funcData["SetAttribute"].stepCount = 0; //-- END --------------------------------------------------------------- } with (this.funcData["SetAttribute"]) { stepCount++; // увеличиваем счётчик проходов var currFile, currFolder, testAttrsRez; switch (jobType) { case 1: // работа с одним файлом currFile = FSO.GetFile(path); // ссылка на текущий объект-файл // Если тест на установку/снятия атрибутов прошёл testAttrsRez = testAttrs(attrs, currFile.Attributes); if (testAttrsRez.length == 0) currFile.Attributes += eval( (attrs.slice(1)).join("+") ); else { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = "[" +ErrInfo+ ']\n"' +attrs[0]+ '":\n' +testAttrsRez.join("\n"); throw this.errors; // вызываем исключение } break; case 2: // работа с одним каталогом currFolder = FSO.GetFolder(path); // ссылка на текущий объект-каталог // Если тест на установку/снятия атрибутов прошёл testAttrsRez = testAttrs(attrs, currFolder.Attributes); if (testAttrsRez.length == 0) currFolder.Attributes += eval( (attrs.slice(1)).join("+") ); else { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = "[" +ErrInfo+ ']\n"' +attrs[0]+ '":\n' +testAttrsRez.join("\n"); throw this.errors; // вызываем исключение } break; case 3: // работа с каталогом и списком файлов определённых расширений if (stepCount == 1) { this.ScanFolder("SetAttribute"); // вызываем метод сканирования каталога delete(this.funcData["SetAttribute"]); // после завершения удаляем данные метода return; } // Если тест на установку/снятия атрибутов прошёл testAttrsRez = testAttrs(attrs, path.Attributes); if (testAttrsRez.length == 0) path.Attributes += eval( (attrs.slice(1)).join("+") ); else { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = "[" +ErrInfo+ '::testAttrs]\n"' +attrs[0]+ '":\n' +testAttrsRez.join("\n"); throw this.errors; // вызываем исключение } var fileList = new Enumerator(path.Files); // создаём объект перечисления файлов в каталоге while (!fileList.atEnd()) { // пробегаем по всем файлам каталога currFile = fileList.item(); // берём новый файл каталога /* Если при вызове метода была установлена маска поиска всех файлов или текущий файл имеет расширение подподающее под введённый шаблон расширений */ if (fileExt == "*" || fileExt.indexOf( FSO.GetExtensionName(currFile.Path).toUpperCase() ) != -1) { // Если тест на установку/снятия атрибутов прошёл testAttrsRez = testAttrs(attrs, currFile.Attributes); if (testAttrsRez.length == 0) currFile.Attributes += eval( (attrs.slice(1)).join("+") ); else { // Устанавливаем объекту ошибок соответствующие поля this.errors.name = ErrInfo; this.errors.description = "[" +ErrInfo+ '::testAttrs]\n"' +attrs[0]+ '":\n' +testAttrsRez.join("\n"); throw this.errors; // вызываем исключение } } fileList.moveNext(); // перемещаемся на следующий файл } } } } //////////////////////////////////////////////////////////////////////////////// //==[ Примеры вызова ]========================================================== //////////////////////////////////////////////////////////////////////////////// /* //--[1]------------------------------------------------------------------------- var myFSO = new FileSystemObj; myFSO.path = "J:\\TestFolder\\"; myFSO.itemCount = 100; myFSO.SetAttribute("1|2|4"); //--[2]------------------------------------------------------------------------- var myFSO = new FileSystemObj("J:\\TestFolder\\*"); myFSO.SetAttribute(true, "1|2|4"); //--[3]------------------------------------------------------------------------- var myFSO = new FileSystemObj; myFSO.SetAttribute("J:\\TestFolder\\.html|.js", "-1|2|-4"); //--[4]------------------------------------------------------------------------- */ var myFSO = new FileSystemObj; try { myFSO.SetAttribute("J:\\TestFolder\\*", true, "-1|2|-4"); } catch (e) { WshShell.Popup(e.description, 0, "Error (myFSO::SetAttribute)", MB_OK | MB_ICONERROR); } FSO.Quit; WshShell.Quit; |
на всякий случай в аттаче отладочный вариант...
Присоединённый файл ( Кол-во скачиваний: 4 )
myFSO__Debug_.zip 5,51 Kb
|