Имя: Пароль:
1C
1C 7.7
v7: 1с77.FSO.Нет доступа к папке. Как продолжить выполнение обработки без прерывния по ошибке?
0 Lsr1
 
08.06.22
12:56
Задача: найти все ДИСКИ и информацию о них,  Папки на каждом диске.
Windows 7,  1с7.7 27движок.
Когда начинается обход подпапок папки Documents and Settings на системном диске, обработка прерывается с сообщением об ошибке.
Папка1уровня=D:\Documents and Settings
Folder=OLE.IFolder=
КолПапок=Folder.SubFolders.Count;
{G:\___БАЗЫ\.....\ЗАГОТОВКИ_ШАБЛОН.ERT(315)}: :
Поскольку ОС Windows 7 физически папки Documents and Settings нет. Есть такая ссылка. Есть папка Users.
Конечно, я могу мсключить определённые папки из сканирования (что сделано в коде), но хотелось бы знать, как грамотно решить проблему, когда не знаешь заранее о какую папку/файл споткнёшься (нет доступа к папке или файлу) .
Вот весь код.

//==================================================
// Функция возвращает элемент коллекции по номеру

//Функция глПолучитьЭлементКоллекцииПоНомеру(Коллекция,Номер) Экспорт
Функция глПолучитьЭлементКоллекцииПоНомеру(Коллекция,Номер) //элементы(Items)
    
    ScrptCtrl=СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language="vbscript";
    ScrptCtrl.AddCode("
    |Function EnumerateCollection(ObjSet,Number)
    |   Count = 0
    |   For Each Obj In ObjSet
    |       If Count = Number Then
    |           Set EnumerateCollection = Obj
    |           Exit Function
    |       End If
    |       Count = Count + 1
    |   Next
    |End Function
    |");
    Возврат ScrptCtrl.Run("EnumerateCollection",Коллекция,Номер);
    
КонецФункции    // глПолучитьЭлементКоллекцииПоНомеру

//==================================================
// Функция возвращает количество элементов коллекции
// т.к. не каждый класс имеет свойство Count. Если оно
// отсутствует, то для определения количества элементов
// в коллекции применяется эта функция

Функция глПолучитьКолВоЭлементовКоллекции(Коллекция)
    
    ScrptCtrl=СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language="vbscript";
    ScrptCtrl.AddCode("
    |Function GetCountCollection(ObjSet)
    |   Count = 0
    |   For Each Obj In ObjSet
    |       Count = Count + 1
    |   Next
    |   GetCountCollection = Count
    |End Function
    |");
    Возврат ScrptCtrl.Run("GetCountCollection",Коллекция);
    
КонецФункции    // глПолучитьКолВоЭлементовКоллекции

//==================================================

// Функция возвращает СОМОбъект по моникеру или имени файла
// Фактически заменяет функцию ПолучитьCOMОбъект в версии 1С 8.х

Функция глПолучитьCOMОбъект(СтрокаПараметров)
    
    ScrptCtrl=СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language="vbscript";
    ScrptCtrl.AddCode("
    |Function GetCOMObject(Str)
    |   Set GetCOMObject = GetObject(Str)
    |End Function
    |");
    Возврат ScrptCtrl.Run("GetCOMObject",СтрокаПараметров);
    
КонецФункции    // глПолучитьCOMОбъект

//==================================================


Процедура Сформировать()
    сообщить("32 найти все ДИСКИ и информацию о них,  Папки на каждом диске. КОЛЛЕКЦИИ (Scripting.FileSystemObject) ");
    ЧасСтарта="";
    МинСтарта="";
    СекСтарта="";
    ТекущееВремя(ЧасСтарта,МинСтарта,СекСтарта);
    FSO = CreateObject("Scripting.FileSystemObject");
    //Для размещения информации о дисках
    ТЗ_Диски=СоздатьОбъект("ТаблицаЗначений");
    ТЗ_Диски.НоваяКолонка("Буква",,,,,6,,);
    ТЗ_Диски.НоваяКолонка("Метка",,,,,16,,);
    ТЗ_Диски.НоваяКолонка("Тип",,,,,6,,);
    ТЗ_Диски.НоваяКолонка("СерНомер",,,,,20,,);
    ТЗ_Диски.НоваяКолонка("Объем",,,,,20,,);
    ТЗ_Диски.НоваяКолонка("Свободно",,,,,20,,);
    ТЗ_Диски.НоваяКолонка("ФайловаяСист",,,,,10,,);
    
    //Для размещения информации о папках 1-го уровня
    ТЗ_Папки=СоздатьОбъект("ТаблицаЗначений");
    ТЗ_Папки.НоваяКолонка("ИмяПапки",,,,,30,,);
    ТЗ_Папки.НоваяКолонка("ТипФайла",,,,,10,,);
    //ТЗ_Папки.НоваяКолонка("Корень",,,,,20,,);
    ТЗ_Папки.НоваяКолонка("ПоложНаДиске",,,,,30,,);
    ТЗ_Папки.НоваяКолонка("РодительскаяПапка",,,,,30,,);
    ТЗ_Папки.НоваяКолонка("ПолныйПуть",,,,,20,,);
    //ТЗ_Папки.НоваяКолонка("РазмерПапки",,,,,20,,);
    ТЗ_Папки.НоваяКолонка("ДатаСозданияПапки",,,,,20,,);
    ТЗ_Папки.НоваяКолонка("ДатаПоследнегоДоступа",,,,,20,,);
    ТЗ_Папки.НоваяКолонка("ДатаПоследнегоИзменения",,,,,20,,);
    ТЗ_Папки.НоваяКолонка("Диск",,,,,10,,);
    ТЗ_Папки.НоваяКолонка("ДлинаПути",,,,,10,,);
    
    //Для размещения информации о папках 2-го уровня
    ТЗ_Папки2=СоздатьОбъект("ТаблицаЗначений");
    ТЗ_Папки2.НоваяКолонка("ИмяПапки",,,,,30,,);
    ТЗ_Папки2.НоваяКолонка("ТипФайла",,,,,10,,);
    //ТЗ_Папки2.НоваяКолонка("Корень",,,,,20,,);
    ТЗ_Папки2.НоваяКолонка("ПоложНаДиске",,,,,30,,);
    ТЗ_Папки2.НоваяКолонка("РодительскаяПапка",,,,,30,,);
    ТЗ_Папки2.НоваяКолонка("ПолныйПуть",,,,,20,,);
    //ТЗ_Папки2.НоваяКолонка("РазмерПапки",,,,,20,,);
    ТЗ_Папки2.НоваяКолонка("ДатаСозданияПапки",,,,,20,,);
    ТЗ_Папки2.НоваяКолонка("ДатаПоследнегоДоступа",,,,,20,,);
    ТЗ_Папки2.НоваяКолонка("ДатаПоследнегоИзменения",,,,,20,,);
    //ТЗ_Папки2.НоваяКолонка("Диск",,,,,10,,);
    ТЗ_Папки2.НоваяКолонка("ДлинаПути",,,,,10,,);
    
    СЗ_ПапкаДляПоиска=СоздатьОбъект("СписокЗначений");
    СЗ_ПапкаДляПоиска.ДобавитьЗначение("Install");
    СЗ_ПапкаДляПоиска.ДобавитьЗначение("_Install");
    //СЗ_ПапкаДляПоиска.ДобавитьЗначение("D:\Install");
    //СЗ_ПапкаДляПоиска.ДобавитьЗначение("D:\_Install");
    
    //Получить все диски, подключенные в системе
    Для A = 67 По 90 Цикл //по латинским буквам  A- Z
        Если fso.DriveExists(Симв(A)) = -1 Тогда    
            Drive = fso.GetDrive(Симв(A));    
            //СЗ_Диски=СоздатьОбъект ("СписокЗначений");
            Если Drive.IsReady = -1 Тогда
                // Диск.DriveType = 1 - Flash накопитель
                // Диск.DriveType = 2 - Локальный жесткий диск
                // Диск.DriveType = 3 - Сетевой диск
                // Диск.DriveType = 4 - CD/DVD дисковод
                БукваДиска=Drive.DriveLetter;
                МеткаДиска=сокрЛП(FSO.GetDrive(Симв(A)).VolumeName);
                ТипДиска=Drive.DriveType;
                СерНомерДиска=сокрЛП(FSO.GetDrive(Симв(A)).SerialNumber);
                
                AvailableSpaceНаДиске=Drive.AvailableSpace;
                FileSystemДиск=Drive.FileSystem;
                FreeSpaceДиск=Drive.FreeSpace;
                PathДиск=Drive.Path;
                RootFolder=Drive.RootFolder.Path;
                TotalSizeДиск=Drive.TotalSize;
                
                //Сообщить("*********************************************");
                //сообщить ("Имеется диск="+БукваДиска);
                //Сообщить("SerialNumber диска="+Симв(A)+": ="+сокрЛП(FSO.GetDrive(Симв(A)).SerialNumber));
                //Сообщить("Имя диска="+Симв(A)+": ="+сокрЛП(FSO.GetDrive(Симв(A)).VolumeName));
                //Сообщить("AvailableSpaceНаДиске="+AvailableSpaceНаДиске);
                //Сообщить("FileSystemДиск="+FileSystemДиск);
                //Сообщить("FreeSpaceДиск="+FreeSpaceДиск);
                //Сообщить("PathДиск="+PathДиск);
                //Сообщить("RootFolder="+RootFolder);
                ////"Ч16.0.,"-преобразовать число в строку длиной 16 символов, 0-без дробной части, разделитель триад -запятая
                //Сообщить("TotalSizeДиск="+формат(TotalSizeДиск,"Ч16.0.,"));
                
                //Если ТипДиска = 3 Тогда  // если это сетевой диск, то укажем сетевой путь
                //    Стр ="Сетевое имя=" + Drive.ShareName;
                //    Сообщить(Стр);
                //КонецЕсли;
                //Сообщить("тип диска="+Симв(A)+": ="+ТипДиска);
                
                ТЗ_Диски.НоваяСтрока();
                ТЗ_Диски.Буква=БукваДиска;
                ТЗ_Диски.Метка=МеткаДиска;
                ТЗ_Диски.Тип=ТипДиска;
                ТЗ_Диски.СерНомер=СерНомерДиска;
                ТЗ_Диски.Объем=формат(TotalSizeДиск,"Ч16.0.,");
                ТЗ_Диски.Свободно=формат(FreeSpaceДиск,"Ч16.0.,");
                ТЗ_Диски.ФайловаяСист=FileSystemДиск;
                //глФРМ(ЧислЗнач, Валюта="", ВыводНулевого=0, РаздТриад="'")
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Сообщить("Найдено дисков="+ТЗ_Диски.КоличествоСтрок());
    
    //ТЗ_Диски.ВыбратьСтроку(,"Имеются диски. посмотри и закрой",);
    
    
    //Перебираю буквы дисков, что бы получить коллекцию папок
    ТЗ_Диски.ВыбратьСтроки();
    //не искать на съемных дисках
    //Для ю=1 по  ТЗ_Диски.КоличествоСтрок() Цикл
    Пока ТЗ_Диски.ПолучитьСтроку()=1 Цикл
        БукваДиска=СокрЛП(ТЗ_Диски.Буква);
        Если (ТЗ_Диски.Тип=1) или  (ТЗ_Диски.Тип=3) или  (ТЗ_Диски.Тип=4) Тогда
            //Сообщить("Тип=1 или 3 или 4. Следующий диск ");
            Продолжить;//следующий диск
        Иначе //HDD, ищем
            Folder = FSO.GetFolder(БукваДиска+":\");//Поиск папок Только в корне диска
            Коллекция1=Folder.SubFolders;
            
            //MsgBox Folder.SubFolders.Count
            КолПапок=Folder.SubFolders.Count;
            //Сообщить("Folder.SubFolders.Count ="+Folder.SubFolders.Count);
            
            //SubFolder1 = Folder.SubFolders.Item("Windows");//элемент=Item Обязательно существующая папка! иначе ругательство
            //MsgBox SubFolder.Path
            //Сообщить("Folder.SubFolders.Item(Windows).Path ="+SubFolder1.Path);
            
            //SubFolder2 = Folder.SubFolders("Windows"); //Обязательно существующая папка! иначе ругательство
            //MsgBox SubFolder.Path
            //Сообщить("Folder.SubFolders(Windows).Path ="+SubFolder2.Path);
            
            Для i=0 по КолПапок-1 Цикл
                ы=глПолучитьЭлементКоллекцииПоНомеру(Коллекция1,i);    
                //Сообщить("ы="+ы);//ы=OLE.IFolder
                //Сообщить("ИмяРеальнойПодпапки="+ы.Name);//
                //Сообщить("*********************************************");
                //Сообщить("Имя папки="+ы.Name);
                //Сообщить("Тип файла="+ы.Type);
                //Сообщить("Папка="+?(ы.IsRootFolder=-1,"корневая","не корневая"));
                //Сообщить("Расположена на диске="+ы.Drive.Path);
                //Сообщить("Родительская папка="+ы.ParentFolder.Name);
                //Сообщить("Полный путь до папки="+ы.Path);
                //Сообщить("Короткое имя папки="+ы.ShortName);
                //Сообщить("Короткий путь до папки="+ы.ShortPath);
                //Сообщить("Размер папки="+Формат(ы.Size,"Ч( )15.2")+" байт");
                //Сообщить("Дата создания папки="+ы.DateCreated);
                //Сообщить("Дата последнего доступа к папке="+ы.DateLastAccessed);
                //Сообщить("Дата последнего изменения папки="+ы.DateLastModified);
                
                ТЗ_Папки.НоваяСтрока();    
                ТЗ_Папки.ИмяПапки=ы.Name;
                ТЗ_Папки.ТипФайла=ы.Type;
                //ТЗ_Папки.Корень=?(ы.IsRootFolder=-1,"корневая","не корневая");
                ТЗ_Папки.ПоложНаДиске=ы.Drive.Path;
                ТЗ_Папки.РодительскаяПапка=ы.ParentFolder.Name;
                ТЗ_Папки.ПолныйПуть=ы.Path;
                //ТЗ_Папки.РазмерПапки=0;
                ТЗ_Папки.ДатаСозданияПапки=ы.DateCreated;
                ТЗ_Папки.ДатаПоследнегоДоступа=ы.DateLastAccessed;
                ТЗ_Папки.ДатаПоследнегоИзменения=ы.DateLastModified;
                ТЗ_Папки.Диск=БукваДиска;
                ТЗ_Папки.ДлинаПути=СтрДлина(СокрЛП(ы.Path));
            КонецЦикла;
        КонецЕсли;
        //Сообщить("Кол-во папок в корне диска="+БукваДиска+" ="+КолПапок);    
    КонецЦикла ;
    
    //Сообщить("Всего коренных папок на всех логических HDD найдено="+ТЗ_Папки.КоличествоСтрок());
    //ТЗ_Папки.ВыбратьСтроку(,"Имеются коренные папки. посмотри и закрой",);
    
    //Теперь можно найти папки 2-го уровня
    КолНеСканПапок=0;
    ТЗ_Папки.ВыбратьСтроки();
    Пока ТЗ_Папки.ПолучитьСтроку()=1 Цикл
        НеСканировать= СокрЛП(ТЗ_Папки.ИмяПапки);
        //Если (НеСканировать = "Documents and Settings") или  (НеСканировать = "System Volume Information")  
        //или  (НеСканировать = "Recycled") или  (НеСканировать = "$RECYCLE.BIN") Тогда
        //    КолНеСканПапок=КолНеСканПапок+1;
        //    Продолжить;//пропустить сканирование подпапок этой папки
        //КонецЕсли;
        
        Папка1уровня=ТЗ_Папки.ПолныйПуть;
        Сообщить("Папка1уровня="+Папка1уровня);
        Folder = FSO.GetFolder(Папка1уровня);//+"\" Поиск папок 2-го уровня
        
        Сообщить("Folder="+Folder+"=");
        
        //On Error Resume Next;//продолжить в случае ошибки
        Коллекция1=Folder.SubFolders;
        
        //MsgBox Folder.SubFolders.Count
        КолПапок=Folder.SubFolders.Count;
        Сообщить("Folder.SubFolders.Count ="+Folder.SubFolders.Count);
        
        //SubFolder1 = Folder.SubFolders.Item("Windows");//элемент=Item Обязательно существующая папка! иначе ругательство
        //MsgBox SubFolder.Path
        //Сообщить("Folder.SubFolders.Item(Windows).Path ="+SubFolder1.Path);
        
        //SubFolder2 = Folder.SubFolders("Windows"); //Обязательно существующая папка! иначе ругательство
        //MsgBox SubFolder.Path
        //Сообщить("Folder.SubFolders(Windows).Path ="+SubFolder2.Path);
        
        Для i=0 по КолПапок-1 Цикл
            ы=глПолучитьЭлементКоллекцииПоНомеру(Коллекция1,i);    
            ТЗ_Папки2.НоваяСтрока();    
            ТЗ_Папки2.ИмяПапки=ы.Name;
            ТЗ_Папки2.ТипФайла=ы.Type;
            //ТЗ_Папки.Корень=?(ы.IsRootFolder=-1,"корневая","не корневая");
            ТЗ_Папки2.ПоложНаДиске=ы.Drive.Path;
            ТЗ_Папки2.РодительскаяПапка=ы.ParentFolder.Name;
            ТЗ_Папки2.ПолныйПуть=ы.Path;
            //ТЗ_Папки.РазмерПапки=0;
            ТЗ_Папки2.ДатаСозданияПапки=ы.DateCreated;
            ТЗ_Папки2.ДатаПоследнегоДоступа=ы.DateLastAccessed;
            ТЗ_Папки2.ДатаПоследнегоИзменения=ы.DateLastModified;
            ТЗ_Папки2.ДлинаПути=СтрДлина(СокрЛП(ы.Path));
            //ТЗ_Папки.Диск=БукваДиска;    
        КонецЦикла;
    КонецЦикла;
    //КонецЕсли;        
    Сообщить("2-го уровня на всех логических HDD просканировано="+ТЗ_Папки2.КоличествоСтрок()+", исключены из анализа="+КолНеСканПапок+" папок 1-го уровня", );
    ЧасФиниш="";
    МинФиниш="";
    СекФиниш="";
    ТекущееВремя(ЧасФиниш,МинФиниш,СекФиниш);
    Сообщить("Время старта="+ЧасСтарта+":"+МинСтарта+":"+СекСтарта+" Время финиша="+ЧасФиниш+":"+МинФиниш+":"+СекФиниш);

    ТЗ_Папки2.ВыбратьСтроку(,"Имеются папки. посмотри и закрой",);
КонецПроцедуры
1 mikecool
 
08.06.22
13:00
Попытка - Исключение
2 АгентБезопасной Нацио
 
08.06.22
13:17
а что, штатные НайтиПервыйФайл()/НайтиСледующийФайл()/АтрибутыФайла() - отменили?
3 Lsr1
 
08.06.22
13:35
Блин, и на старуху бывает проруха. про слона то я и забыл.
(1) СПАСИБО!
(2) Нет, не отменили, но у штатной файловой системы 1С7.7, на сколько я помню, есть весьма серьезные ограничения.
Вот часть, которую исправил.
            
            Для i=0 по КолПапок-1 Цикл
                ы=глПолучитьЭлементКоллекцииПоНомеру(Коллекция1,i);    
                Попытка
                    Если ПустоеЗначение(ы.Size)=0 Тогда
                        ТЗ_Папки.НоваяСтрока();    
                        ТЗ_Папки.ИмяПапки=ы.Name;
                        ТЗ_Папки.ТипФайла=ы.Type;
                        //ТЗ_Папки.Корень=?(ы.IsRootFolder=-1,"корневая","не корневая");
                        ТЗ_Папки.ПоложНаДиске=ы.Drive.Path;
                        ТЗ_Папки.РодительскаяПапка=ы.ParentFolder.Name;
                        ТЗ_Папки.ПолныйПуть=ы.Path;
                        //ТЗ_Папки.РазмерПапки=0;
                        ТЗ_Папки.ДатаСозданияПапки=ы.DateCreated;
                        ТЗ_Папки.ДатаПоследнегоДоступа=ы.DateLastAccessed;
                        ТЗ_Папки.ДатаПоследнегоИзменения=ы.DateLastModified;
                        ТЗ_Папки.Диск=БукваДиска;
                        ТЗ_Папки.ДлинаПути=СтрДлина(СокрЛП(ы.Path));
                    КонецЕсли;
                    
                Исключение
                    //Сообщить(ОписаниеОшибки());
                КонецПопытки;
                
            КонецЦикла;
4 Lsr1
 
08.06.22
15:54
(2) Нашёл здесь :_https://newexp.ru/public/21208/
Методы ФС ГАРАНТИРОВАНО (прошу прощения за каплок, но иного способа выделения здесь не знаю) работают только внутри каталога рабочей базы. Потомушто каталог базы в полном доступе. Так надо :)) А вот вне БД встречаются места, не обремененные полным доступом для вас, как юзера...
Вы, конечно, можете написать ФС.КопироватьФайл(бла-бла-бла), только вот этот метод ничегошеньки не сообщит, если копирование не произойдет. И причину не сообщит. И даже не смотрите в сторону Попытка...Исключение: прерывания оси 1С не видит...
Потому рекомендую пользовать FileSystemObject из Windows Script Host... Это все-таки компонента, "встроенная" в ось, потому работать будет с бОльшей гарантией, чем любая ВК и даже 1С ;)
И побогаче будет. И отрабатывает прерывания исполнения...
5 MWWRuza
 
гуру
09.06.22
21:37
(4) Вы, конечно, можете написать ФС.КопироватьФайл(бла-бла-бла), только вот этот метод ничегошеньки не сообщит, если копирование не произойдет. И причину не сообщит. И даже не смотрите в сторону Попытка...Исключение: прерывания оси 1С не видит...

Ну, или, вариант, проверять наличие файла в целевом каталоге после копирования...

Типо так, фрагмент из рабочей конфы, выгрузка файлов из бэк 1С во фронты(кассы):

Процедура ЗаписатьФайл(КаталогОбмена, ИмяФайлаВыгрузкиCCRS_POS, мИмяФайла)
    ИмяФайлаВыгрузки    = КаталогОбмена + ?(Прав(КаталогОбмена, 1) <> "\", "\", "") + "inp\" + мИмяФайла;            
    Если ФС.СуществуетФайл(ИмяФайлаВыгрузкиCCRS_POS)=1 Тогда
        ФС.КопироватьФайл(ИмяФайлаВыгрузкиCCRS_POS,ИмяФайлаВыгрузки,0);
        Если ФС.СуществуетФайл(ИмяФайлаВыгрузки)=1 Тогда
            Сообщить ("Выгружен "+ ИмяФайлаВыгрузки);    
        Иначе  
            Сообщить ("Не удалось создать файл "+ ИмяФайлаВыгрузки);        
        КонецЕсли;    
    КонецЕсли;    
КонецПроцедуры //ЗаписатьФайл
6 Злопчинский
 
10.06.22
00:13
(5) пичалька будет в том что если ИмяФайлаВыгрузки по месту назначения уже существует, но у кеода нет прав доступа, то этот код соврет... Поэтому сначала проверяем наличие файла по месту назначения, удаляем файл по месту назначения, проверяем на отсутствие файла и только потом копируем. И даже такой сценарий содержит дырки если права на удалением создание разные (точно не помню, могу тут лажать). Но описанный подход лучше чем код в пред.посте
7 MWWRuza
 
гуру
10.06.22
08:55
(6) Здесь, я с тобой полностью согласен... Просто писать чего-то ради демонстрации, было лень. Выдрал из рабочей конфы рабочий кусок. А там, такой ситуации быть просто не может, по определению - файлы удаляются фронтом автоматически, при загрузке товара в кассовую программу. И даже, если предположить, что по каким-то причинам этого не произошло - ну, например кассовая программа не запущена, то все равно не этого не произойдет - там имена файлов(мИмяФайла) каждую выгрузку уникальны(к стандартному имени файла, добавляется число секунд с начала года, и кассовая программа грузит файлы "по маске" - "ИмяНужногоФайла*.xml"). Сделано так для того, что если в файл закралась ошибка, то касовая программа не просто удаляет файл после загрузки всего, что смогла, а перемещает его в подпапку "EROR" в папке загрузки, для дальнейшего анализа и исправления ошибок в базе, и в таком случае, файлы не перезаписываются, т.к. имена у них уникальные.
А в общем случае, да, при использовании такого алгоритма, надо проверять наличие файла перед копированием.
А с правами на создание/удаление... Я как-то не заморачивался. Тут не скажу.
8 uno-group
 
10.06.22
11:57
Обычно из 1с не нужно работать с файлами валяющимися где попало с какими попало правами доступа. ИМХО это задача админа раздать нормально права на папки и файлы.