Форум » Clipper » Проблема с TRUENAME » Ответить

Проблема с TRUENAME

Sergy: Странная проблема происходит под WinXP/Win2003: вызов функции TRUENAME может в половине случаев привести к GPF, в другой половине - нормально отработать. Т.е. бывает даже так: две машины в сети стоят рядом, на одной GPF, на другой - нет. Кроме того, вероятность GPF меняется в зависимости от "сборки" экзешника. Поясню: добавил пару-тройку функция в программу - GPF происходит на 8 машинах из десяти. Добавил еще пару функций - резко падает - примерно до 2 из 10. Немного сумбурно, но вот простейший цикл: FOR i:=1 TO 1000 sx := TRUNAME("c:\aaa.txt") NEXT i приводит к 100% GPF на любой машине. Конфигурация: WinXP SP2, Win2003 (remote desktop), Clipper 5.2e (pm), Blinker 6.0, CT, Nanforum Toolkit (только для разгрузки проца)

Ответов - 14

Григорьев Владимир: А что эта за функция TRUENAME()? Может быть ей просто не пользоваться, и все проблемы? Если эта функция из CTOOLS, то доверять этой библиотеке нельзя. Я какую-то версию смотрел этой библиотеки -написана очень плохо!

Dima: Sergy пишет: Странная проблема происходит под WinXP/Win2003: вызов функции TRUENAME может в половине случаев привести к GPF Аналогично. Решил проблему просто. Эту функцию вызываю всего один раз в программе и закидываю результат в переменную , откуда и беру в дальнейшем результат. Более GPF не было :) PS В моей задаче такого разового вызова хватает , у тебя может быть иная ситуация.

Dima: Григорьев Владимир пишет: А что эта за функция TRUENAME()? TRUENAME() Преобразует заданный путь доступа к стандартной форме. ------------------------------------------------------------------------------ Синтаксис TRUENAME(<cPathDesignation>) --> cStandardizedPath Параметры <cPathDesignation> - символьная строка, задающая путь доступа, преобразуемый к стандартной для DOS форме. Возвращаемое значение cStandardizedPath - символьная строка, содержащая путь доступа при корректном задании пути, а иначе пустая строка. Описание Функция преобразует путь доступа, заданный относительно диска или относительно текущей директории, к принятому в DOS формату: <имя диска>:\<директория 1>\...\<директория N> Функция не проверяет реального существования конкретного пути, однако если путь задан некорректно или недоступен указанный диск, то возвращается пустая строка.


Sergy: Аналогично. Решил проблему просто. Эту функцию вызываю всего один раз в программе и закидываю результат в переменную , откуда и беру в дальнейшем результат. Более GPF не было :) PS В моей задаче такого разового вызова хватает , у тебя может быть иная ситуация. Все к тому идет, что придется от функции отказываться... вставил ее несколько вызовов в процессе выбора файла и списка (а-ля панели Far) +/- кое-где проверяю тип/имя диска по пути, который указал юзер (для сохранения, например) У кого-то есть еще печальный опыт или кто-то смог побороть мерзавку TRUENAME ?

Григорьев Владимир: В связи с наличием исходного кода [x]Harbour сейчас имеется хорошая возможность работать с исходными текстами функций. Если в [x]Harbour функция TRUENAME() реализована, то вы можете перенести ее исходный код на Clipper, откомпилировать и использовать со своей программой.

Pasha: не выйдет там реализована только версия для win32-платформы через винапишную функцию

ort: Sergy пишет: У кого-то есть еще печальный опыт или кто-то смог побороть мерзавку TRUENAME ? Меня TRUENAME в последнее время сильно достала. Могу сказать, что побороть ее я не сумел (или не знаю). После многочисленных попыток избавиться от GPF плюнул я на неё и написал свою функцию: (код, может быть, немного корявый, но работает как оригинальная TrueName()) Function MyTrueName(cPathName,lLongName) LOCAL nnn, lSetAtMupa, cTrueName, lAddDiskName := .T. LOCAL cCurDir := CurDir() DEFAULT lLongName TO .F. IF cPathName = "\\" // Сетевой путь RETURN IF(lLongName,FN_ToLong(cPathName),cPathName) ENDIF IF cPathName == ".." cTrueName := IF( (nnn:=At("\",cCurDir))>0, Left(cCurDir,nnn-1), "") lAddDiskName := !(cCurDir == "") ELSEIF Left(cPathName,1) == "." cTrueName := cCurDir + SubStr(cPathName,2) ELSEIF At(":",cPathName) == 0 .AND. At("\",cPathName) == 0 cTrueName := cCurDir+"\"+cPathName ELSEIF Right(cPathName,1) == "\" .AND. Len(cPathName) > 1 cTrueName := "" lAddDiskName := .F. ELSE cTrueName := cPathName ENDIF IF At(":",cTrueName) == 0 .AND. lAddDiskName cTrueName := DiskName()+":\"+cTrueName ENDIF lSetAtMupa := cSetAtMupa(.T.) cTrueName := AtRepl("\.", cTrueName, "\") cTrueName := AtRepl("\\", cTrueName, "\") cSetAtMupa(lSetAtMupa) RETURN IF(lLongName,FN_ToLong(cTrueName),cTrueName)

Sergy: Спасибо. Вопросик, откуда это: FN_ToLong() cSetAtMupa() ?

ort: CSETATMUPA() из Clipper Tools (используется для функции AtRepl) Переключает режим работы функций семейства ATxxxx(). ───────────────────────────────────────────────────────────────────────── Синтаксис CSETATMUPA([<lNewMode>]) --> lOldMode Параметры <lNewMode> - необязательный логический параметр, задающий при значении .T. включение, а при значении .F. выключение режима прохода по символам для всех функций семейства ATxxxx(). По умолчанию состояние режима прохода по символам не изменяется. FN_ToLong() - слегка измененная LF_ToLong() из библиотеки LFN (Long File Names): LF_TOLONG() - Get the canonical long name for a short file name Так что можно написать LF_ToLong() или вообще убрать.

Sergy: спасибо

ort: Sergy Пожалуйста. Кстати, работа MyTrueName() проверена на таких примерах: . .. \ ARRAY.TXT .\ARRAY.TXT, \ORT\.\ORT\.\ARRAY.TXT, .\ORT\.\ORT\.\ARRAY.TXT, D:\ORT\PRG\ARRAY.TXT, \ORT\PRG\ Если возникнет еще какой-то вариант - поделитесь.

suv2: Функция совсем плохая, работает с ошибками + ничего совсем не умеет (это в общем-то и видно по ее небольшому размеру. Я просто посмотрел на свою аналогичную функцию - она гораздо объемнее по количеству строк) В примерах ниже когда я говорю "надо" - подразумевается результат, выдаваемый командой дос truename чем не угодил путь со слешем на конце? ?mytruename("C:\TEMP\") = "" Надо C:\TEMP\ cd C:\TEMP ?mytruename("..\config.sys") = ""C:\TEMP.\config.sys"" А надо c:\config.sys cd C:\TEMP ?mytruename("C:") = ""C:" ?mytruename("C:file.ext") = ""C:file.ext" А надо C:\TEMP и C:\TEMP\file.ext- подставлять дефолтный каталог на устройстве cd C:\TEMP ?mytruename("file.ext") = "file.ext" А надо "C:\TEMP\file.ext" cd C:\TEMP md D1 cd D1 md D2 cd M2 ?mytruename("..") = ""C:\TEMP" А надо C:\TEMP\D1 C: ?mytruename("\temp\..\..\..\file.ext") = "c:\temp\file.ext" а это вообще невозможный случай ?mytruename("c:\..\file.ext") = "c:\file.ext" тоже невозможный случай и так далее, и так далее...

ort: suv2 пишет: Функция совсем плохая, работает с ошибками + ничего совсем не умеет На тех данных, что я использую, результат работы TrueName() равен результату MyTrueName(), что меня вполне устраивает. Конечно, если будут случаи несоответствия - буду править.

suv2: ort пишет: Конечно, если будут случаи несоответствия - буду править ты просил случаи - я тебе их дал



полная версия страницы