Что нового

Файловая система Работа с длинными именами файлов

Oki

Продвинутый
Сообщения
452
Репутация
62
Некоторые функции приводят к ошибкам при работе с длинными именами файлов. Какие существуют приёмы для борьбы с этим явлением?
 

Alecsis

Осваивающий
Сообщения
101
Репутация
41
Некоторые функции приводят к ошибкам при работе с длинными именами файлов. Какие существуют приёмы для борьбы с этим явлением?
Перед именем файла вставляем префикс "\\?\" — в Win7 и Win10 работает.
Код:
#pragma compile(Console, True)
#pragma compile(UPX, False)
Opt('MustDeclareVars', True)
Local $sName, $sExtraLong, $hFile
;
$sName = @ScriptDir & '\zxcvaeroiyerpyieprtiyeroyiwyilfpowieylwpoiywe[iy[ti,w]piyqw]p\weoriutwpoeriyuwpuypweoruywpoeriuywpoeriuctqwpoiutkpcwoierutpvwoeiruwpvoituywjver\paiwrupaeiorutpqorweiuqnweixuqiweurytocqiuryefmpaiuycpaiuyecfgmq\35468er7yw98r7ya69er8y7aqe65rfh4bz6df57yud6gyk4d68tf7ya68er7y6a8e7t4h35b4zdf357g8asefy7\zzz.txt'
$hFile = FileOpen($sName)
ConsoleWrite($hFile & @CRLF)
ConsoleWrite(FileRead($hFile) & @CRLF)
FileClose($hFile)
;
$sExtraLong = '\\?\' & $sName
$hFile = FileOpen($sExtraLong)
ConsoleWrite($hFile & @CRLF)
ConsoleWrite(FileRead($hFile) & @CRLF)
FileClose($hFile)
Exit

PS1 Кстати, это описано в документации мелкомягких, например здесь
https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
PS2 и даже под WinXP прокатило :good:
 
Последнее редактирование:
  • Like
Реакции: Oki

Alecsis

Осваивающий
Сообщения
101
Репутация
41
Вы правы «на все 146%» ©, без шуток и приколов. Однако ж согласно ссылке сие актуально только под Win10+…
Т.о. ковыряйте реестр и/или системные политики. Ежели Вам кто-то позволит это делать :hmm:
И таки да, не факт, что на чужом компе есть Win10 вообще и её = Wind'ы = нужные настройки в частности…
 
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10
Вы правы «на все 146%» ©, без шуток и приколов. Однако ж согласно ссылке сие актуально только под Win10+…
Т.о. ковыряйте реестр и/или системные политики. Ежели Вам кто-то позволит это делать :hmm:
И таки да, не факт, что на чужом компе есть Win10 вообще и её = Wind'ы = нужные настройки в частности…
Ну состоит отметить, если это для личного пользования то вполне рабоче. Так же из личного опыта сейчас в большинстве случаев у всех стоит win10 и выше.
Мы предлагаем автору методы решения, а он уже сам выбирает какой ему будет удобнее и проще.
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
62
Ну состоит отметить, если это для личного пользования то вполне рабоче.
Не совсем: меняя настройку, которая позволяет длинные имена, открываем также и право создания ещё более длинных имён сторонними программами. По такому пути поэтому не хотелось идти изначально.

Решение с префиксом "\\?\" лично меня устроило. Microsoft обещает работу этого решения только начиная с определённой сборки системы. Если станет постоянным стандартом, то почему бы не вставлять этот префикс автоматически в код каждой функции? Возможно, удобнее будет добавить параметр для AutoItSetOption(), изменяющий это поведение. Если с этим нет никаких подводных камней (типа замедления работы, ошибок в случае слишком коротких имён или чего-то в этом роде), то можно предложить разработчикам языка.
Сообщение автоматически объединено:

Перед именем файла вставляем префикс "\\?\"
Всё-таки не всегда помогает. :-(
Код:
#include <File.au3>
#include <WinAPIShellEx.au3>
$sPath = "\\?\C:\Tmp\"
For $i = 11 To 95
    $sPath &= "w" & $i
Next
_FileCreate($sPath)
_WinAPI_ShellOpenFolderAndSelectItems($sPath)
MsgBox(4096, "", "Script terminated.")
Функция из библиотеки "WinAPIShellEx" свою работу не выполняет, тогда как функция из библиотеки "File" срабатывает. Если убрать префикс, сократив имя файла, то работает.
Код:
#include <File.au3>
#include <WinAPIShellEx.au3>
$sPath = "C:\Tmp\"
For $i = 11 To 94
    $sPath &= "w" & $i
Next
_FileCreate($sPath)
_WinAPI_ShellOpenFolderAndSelectItems($sPath)
MsgBox(4096, "", "Script terminated.")
 
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10
Не совсем: меняя настройку, которая позволяет длинные имена, открываем также и право создания ещё более длинных имён сторонними программами. По такому пути поэтому не хотелось идти изначально.

Решение с префиксом "\\?\" лично меня устроило. Microsoft обещает работу этого решения только начиная с определённой сборки системы. Если станет постоянным стандартом, то почему бы не вставлять этот префикс автоматически в код каждой функции? Возможно, удобнее будет добавить параметр для AutoItSetOption(), изменяющий это поведение. Если с этим нет никаких подводных камней (типа замедления работы, ошибок в случае слишком коротких имён или чего-то в этом роде), то можно предложить разработчикам языка.
Сообщение автоматически объединено:


Всё-таки не всегда помогает. :-(
Код:
#include <File.au3>
#include <WinAPIShellEx.au3>
$sPath = "\\?\C:\Tmp\"
For $i = 11 To 95
    $sPath &= "w" & $i
Next
_FileCreate($sPath)
_WinAPI_ShellOpenFolderAndSelectItems($sPath)
MsgBox(4096, "", "Script terminated.")
Функция из библиотеки "WinAPIShellEx" свою работу не выполняет, тогда как функция из библиотеки "File" срабатывает. Если убрать префикс, сократив имя файла, то работает.
Код:
#include <File.au3>
#include <WinAPIShellEx.au3>
$sPath = "C:\Tmp\"
For $i = 11 To 94
    $sPath &= "w" & $i
Next
_FileCreate($sPath)
_WinAPI_ShellOpenFolderAndSelectItems($sPath)
MsgBox(4096, "", "Script terminated.")
А оказывается мой метод не такой уж и плохой, да ? :D
Тем более, что вам мешает только если нужно редактировать реестр и после возвращать в исходное состояние, да скорость чуть упадёт, но проблему решит.
 
Автор
Oki

Oki

Продвинутый
Сообщения
452
Репутация
62
А оказывается мой метод не такой уж и плохой, да ? :D
Тем более, что вам мешает только если нужно редактировать реестр и после возвращать в исходное состояние, да скорость чуть упадёт, но проблему решит.
Присваивать себе метод, который в поиске без указания на AutoIt выскакивает первым, а потому прочитан до создания топика, это сильно. Если бы хотя бы скрипт, автоматизирующий эти редактирования туда-сюда, был предложен, то ещё куда ни шло. А не линк на статью, в котором, кстати, оба метода указаны.
 
Последнее редактирование:
Верх