Есть реальные пути, но они искажены символами верхнего и нижнего регистра.
Есть функция, которая позволяет получать точный путь учитывая регистр:
Минусы этого метода:
1. Он очень медленный, если проверять тысячи файлов
2. Номер информации может меняться на разных системах, к примеру на 7-ке - 180, на Win10 - 194, возможно какие-то ещё есть ...
3. Нашёл недавно ещё один минус - не для любых файлов это работает, к примеру, не для всех файлов DLL возвращается нужная информация. Но это можно поправить: получить ИМЯ через нулевой индекс и направить родительский путь обратно в функцию.
Есть ли способ сделать подобное на API функциях, чтобы было более стабильно?
В системе где-то это есть - если вызвать диалог "Свойства" для любого файла/каталога, то там будет путь и имя в правильном регистре.
Есть более простой метод:
Но он выдаёт ошибку при нахождении файла в скрытых/системных папках:
Такие пути не получить, у меня WIN10
Конечно можно поставить проверки и ошибок не будет, но , возможно найдётся метод без Shell.Application...
Есть функция, которая позволяет получать точный путь учитывая регистр:
Код:
$sFile='D:\CollectionFiles2\ПрИвЕт\Name.txt' ; реальный путь учитывая регистр
$sFile='d:\collectionfiles2\привет\name.txt' ; искажённый
; $sPath=_Get_Info_Path($sFile,180) ; для Windows 7
$sPath=_Get_Info_Path($sFile,194) ; для Windows 10
MsgBox(4096,'Переменная $sPath',$sPath)
$sFile='C:\Windows\System32\explorer.exe' ; реальный путь учитывая регистр
$sFile='C:\WINDOWS\SYSTEM32\EXPLORER.EXE' ; искажённый
; $sPath=_Get_Info_Path($sFile,180) ; для Windows 7
$sPath=_Get_Info_Path($sFile,194) ; для Windows 10
MsgBox(4096,'Переменная $sPath',$sPath)
$sFile='C:\Windows\System32\DriverStore\' ; реальный путь учитывая регистр
$sFile='c:\windows\SYSTEM32\driverstore\' ; искажённый
; $sPath=_Get_Info_Path($sFile,180) ; для Windows 7
$sPath=_Get_Info_Path($sFile,194) ; для Windows 10
MsgBox(4096,'Переменная $sPath',$sPath)
Func _Get_Info_Path($sFile,$iIndex)
$oApp=ObjCreate('Shell.Application')
If IsObj($oApp)Then
$aPath=StringRegExp($sFile,'(.*\\)(.+\\?)',3)
$oObject=$oApp.NameSpace($aPath[0])
If IsObj($oObject)Then
$oName=$oObject.ParseName($aPath[1])
If IsObj($oName)Then Return $oObject.GetDetailsOf($oName,$iIndex)
EndIf
EndIf
Return $sFile
EndFunc
Минусы этого метода:
1. Он очень медленный, если проверять тысячи файлов
2. Номер информации может меняться на разных системах, к примеру на 7-ке - 180, на Win10 - 194, возможно какие-то ещё есть ...
3. Нашёл недавно ещё один минус - не для любых файлов это работает, к примеру, не для всех файлов DLL возвращается нужная информация. Но это можно поправить: получить ИМЯ через нулевой индекс и направить родительский путь обратно в функцию.
Есть ли способ сделать подобное на API функциях, чтобы было более стабильно?
В системе где-то это есть - если вызвать диалог "Свойства" для любого файла/каталога, то там будет путь и имя в правильном регистре.
Сообщение автоматически объединено:
Есть более простой метод:
Код:
Func __Get_Info_Path($sFile)
$aPath=StringRegExp($sFile,'(.*\\)([^\\]+)(\\?)',3)
$oApp=ObjCreate('Shell.Application')
Return $oApp.NameSpace($aPath[0]).ParseName($aPath[1]).Path
EndFunc
Но он выдаёт ошибку при нахождении файла в скрытых/системных папках:
Код:
$sFile='C:\WINDOWS\Fonts\arial.ttf'
$sFile='C:\Windows\Downloaded Program Files\desktop.ini'
Такие пути не получить, у меня WIN10
Конечно можно поставить проверки и ошибок не будет, но , возможно найдётся метод без Shell.Application...
Последнее редактирование: