Autorun
Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер
AkulaBig
Ясно.
Ну а я установил 24H2, но это ничего не дало (ожидаемо). Видимо, какие-то особенности вашей системы. Код ThreadWatchLang просмотрел, но опять же, нечего подозрительного не вижу. Куда копать в данный момент идей нет.
Могу пока сделать фикс положения, вот только тогда ошибка замаскируется. Или можно выводить окно где-то в углу, чтобы и читалось, и сразу было ясно, что опять вылез косяк.
Ясно.
Ну а я установил 24H2, но это ничего не дало (ожидаемо). Видимо, какие-то особенности вашей системы. Код ThreadWatchLang просмотрел, но опять же, нечего подозрительного не вижу. Куда копать в данный момент идей нет.
Могу пока сделать фикс положения, вот только тогда ошибка замаскируется. Или можно выводить окно где-то в углу, чтобы и читалось, и сразу было ясно, что опять вылез косяк.
Очень странно. Попробую еще в Песочнице. Чище оськи не найдешь.Loopback писал(а):Ну а я установил 24H2, но это ничего не дало (ожидаемо)
Может просто выводить по центру экрана, а не ТС? И еще ведь не надо забывать, что только эта ошибка у меня автозакрывается. Даже на ТС32.Loopback писал(а):Или можно выводить окно где-то в углу, чтобы и читалось, и сразу было ясно, что опять вылез косяк.
Loopback
Попробовал в Песочнице. Никаких изменений. Так что даже представить не могу, почему у вас ошибка не срабатывает. Включите Песочницу. Чудес ведь не бывает. Должно одинаково работать.
Попробовал в Песочнице. Никаких изменений. Так что даже представить не могу, почему у вас ошибка не срабатывает. Включите Песочницу. Чудес ведь не бывает. Должно одинаково работать.
Вообще Винда сама отслеживает вроде-бы, но настройками можно изменить.jentoso писал(а):А потом не возникнут проблемы с тем, что у кого-то два и более мониторов и определять куда именно выводить, отлично от центра самого TC?
AkulaBig писал(а):Может просто выводить по центру экрана, а не ТС?
Это самое простое, просто тогда будет непонятно, что произошёл сбой. Впрочем, раз окно самозакрывается, то вообще никакой разницы.AkulaBig писал(а): что только эта ошибка у меня автозакрывается. Даже на ТС32.
В принципе окно у меня тоже иногда закрывалось, но только под x64, это другой, старый недолеченный баг. В 32-битной ни разу. При этом отладочный вывод нормальный, так что это не та проблема.
Песочница не хочет ставиться на гостевой системе. Но в этом, думаю, нет необходимости, потому что система только что была развернута и обновлена, совершенно чистая.AkulaBig писал(а):Включите Песочницу.
О, ещё как бывают. Иначе бы все баги всегда повторялись.AkulaBig писал(а):Чудес ведь не бывает.
Я так сделал:Loopback писал(а):Нужно туда добавить ключ
Код: Выделить всё
ShellExec /SW_HIDE /WAIT %COMSPEC% '/c setx OIT_DATA_PATH C:\'
Системный формат времени: 2025/09/02
Код: Выделить всё
SetEnv cmonth %"Date('yyyy-MM',now())" # -->2025-09
SetEnv tday %"Date('yyyy-MM-dd',now())" # -->2025-09-02
SetEnv cmonth %"Date('yyyy-MM')" # -->2025/09/02
SetEnv tday %"Date('yyyy-MM-dd')" # -->2025/09/02
Loopback
Autorun 2.2.19.1, пример из справки ["Синтаксис" -> "Функции"] не работает?
Autorun 2.2.19.1, пример из справки ["Синтаксис" -> "Функции"] не работает?
Код: Выделить всё
Local sysdir
DllCall("GetSystemDirectoryW", "wstr:256", @sysdir, "int", 255)Orion9
В 2.2.19.1 нет, не работает, исправлено в этой.
В 2.2.19.1 нет, не работает, исправлено в этой.
Loopback
Вот что значит быстро читать. Просмотрел этот момент. Не ожидал, что будет так много сообщений за время моего отсутствия, пришлось ускориться. Но обновленную версию видел и скачал, просто подумал, что она связана с багофиксами, которые обсуждались, и как-то не вкурил я в эту фразу: "регресс с версии 2.2.17"
В общем, хотел использовать эту фичу в вызове GetVolumePathNameW, но поскольку такой формат записи не сработал, пришлось откатиться на буфер. Сейчас, думаю, менять уже ничего не буду, так как таким образом останется совместимость с 2.2.19.1
Замутил я тут одну тему под стать возможностям современного Autorun, оказалось, ему вполне по силам - вывести информацию о фрагментации файлов в отдельном наборе колонок и дополнительном окне подсказки. Результатом очень даже доволен.
[cut="autorun.cfg"][/cut]
Код кнопки стандартный. При желании номер команды можно заменить:
Небольшое описание переменных:
FRAG_SHOW - просто глобальная переменная, которая используется внутренне. Ее первоначальное значение ни на что не влияет.
FRAG_LINES - количество строк в подсказке. Т.к. фрагментов может быть сотни и тысячи, размер посказки нужно как-то ограничивать.
FRAG_BUFFER - размер буфера в килобайтах. Это буфер, в который возвращается информация о фрагментах. Но поскольку фрагментов может быть очень много, всё в буфер может не влезть. В таких случаях рекомендуют делать повторные вызовы, но я не стал этим загоняться. При желании можно увеличить буфер, если нужно видеть большее количество записей. 32Кб дают где-то 2000 записей.
FRAG_NUM - если true, то в кастомное поле "Frag" будет выводится только числовой тип данных. По умолчанию это поле строковое и может содержать строку формата "1/3*2", где 1 - число реальных фрагментов, 3 - число записей в MFT, 2 - попадание во второй диапазон.
FRAG_ENTRY - если true, то в кастомное поле "Frag" будет попадать информация о вхождении в диапазон после звездочки.
FRAG_START1 и FRAG_START3 - начало и конец диапазона в кластерном пространстве. Информация о диапазоне также выводится в поле "FragEntry". Удобно, если нужно найти файлы, попадающие в ту или иную область на диске.
Поле "FragNum" содержит информацию только в числовом выражении.
Есть кое-какие ограничения в работе, но о них нужно отдельно написать. Завтра, по возможности, это сделаю.
Вот что значит быстро читать. Просмотрел этот момент. Не ожидал, что будет так много сообщений за время моего отсутствия, пришлось ускориться. Но обновленную версию видел и скачал, просто подумал, что она связана с багофиксами, которые обсуждались, и как-то не вкурил я в эту фразу: "регресс с версии 2.2.17"
В общем, хотел использовать эту фичу в вызове GetVolumePathNameW, но поскольку такой формат записи не сработал, пришлось откатиться на буфер. Сейчас, думаю, менять уже ничего не буду, так как таким образом останется совместимость с 2.2.19.1
Замутил я тут одну тему под стать возможностям современного Autorun, оказалось, ему вполне по силам - вывести информацию о фрагментации файлов в отдельном наборе колонок и дополнительном окне подсказки. Результатом очень даже доволен.
[cut="autorun.cfg"]
Код: Выделить всё
Pragma AutorunPluginFields "Frag:::FileVCN" "FragNum::ft_numeric_32:NumVCN" "FragEntry::ft_numeric_32:EntryVCN"
# параметры фрагментации
Global FRAG_SHOW = false, _
FRAG_LINES = 40, _
FRAG_BUFFER = 32, _
FRAG_NUM = false, _
FRAG_ENTRY = false
Global FRAG_START1 = 100000000, FRAG_END1 = 110000000, _
FRAG_START2 = 200000000, FRAG_END2 = 220000000, _
FRAG_START3 = 0, FRAG_END3 = 100000
RegisterCommand 70400 ReadFileVCN
Func ReadFileVCN(lParam)
Local bClipBoard = IsPressed(0x11)
Local sPath = RequestCopyDataInfo("SP")
Local sName = RequestCopyDataInfo("SN")
Local sFile = sPath & sName
If Not FileExist(sFile) Then
ShowHint("Файл не существует " & sFile)
Return
Endif
FRAG_SHOW = Not bClipBoard
FileVCN(sFile, 0, bClipBoard)
FRAG_SHOW = 0
EndFunc
Func NumVCN(FileName, FieldIndex, UnitIndex)
FRAG_NUM = 1
Local n = FileVCN(FileName, 0, 0)
FRAG_NUM = 0
Return n
EndFunc
Func EntryVCN(FileName, FieldIndex, UnitIndex)
Local f = FRAG_ENTRY
FRAG_ENTRY = 2
Local n = FileVCN(FileName, 0, 0)
FRAG_ENTRY = f
Return n
EndFunc
Func FileVCN(FileName, FieldIndex, UnitIndex)
Local Const OPEN_EXISTING = 3, _
FSCTL_GET_RETRIEVAL_POINTERS = 0x090073, _
ERROR_MORE_DATA = 234
Local Bytes = 0
Local hFile = 0
Local fs = FileGetSize(FileName)
Local sVolume, nCluster, nSector, nFree, nTotal, nRet, nSysErr, nEntry = 0, Dbg = 0
Static bf1 = Buffer(8)
bf1.Zero()
DllCall("GetVolumePathNameW", "wstr", FileName, "ptr", bf1.ptr, "dword", bf1.size)
sVolume = bf1.GetStr()
DllCall("GetDiskFreeSpaceW", "wstr", sVolume, _
"dword*", @nCluster, "dword*", @nSector, _
"dword*", @nFree, "dword*", @nTotal)
bf1.Zero()
Static bf2 = Buffer(1024*FRAG_BUFFER)
bf2.Zero()
hFile = DllCall("CreateFileW", "wstr", FileName, _
"dword", 0, _
"dword", 3, _
"ptr", 0, _
"dword", OPEN_EXISTING, _
"dword", 0, _
"ptr", 0, "handle")
If hFile > 0 Then
nRet = DllCall("DeviceIoControl", "handle", hFile, _
"dword", FSCTL_GET_RETRIEVAL_POINTERS, _
"ptr", bf1.ptr, _
"dword", bf1.size, _
"ptr", bf2.ptr, _
"dword", bf2.size, _
"dword*", @Bytes, _
'ptr', 0)
nSysErr = SYSERROR
DllCall("CloseHandle", "handle", hFile)
Endif
Local c = bf2.GetNum(), _
vcn = bf2.GetNum(8,"dword"),
lcn = bf2.GetNum(24,"dword"), _
next_vcn = 0, _
last_vcn = bf2.GetNum((c-1)*16+16,"dword"), _
prev_lcn = 0, _
clus = 0, _
contig = 0, _
i = 0
Local sOut
sOut = StrFormat("%3u %8u %12s", 1, vcn, SizeFormat(lcn, 0, "B", 0, 2))
For i = 0 To c - 1
next_vcn = bf2.GetNum(i*16+16,"dword")
prev_lcn = lcn
lcn = bf2.GetNum((i+1)*16+24,"dword")
clus = next_vcn - vcn
If lcn - clus = prev_lcn Then contig += 1
If FRAG_ENTRY Then
Local lcn_start = prev_lcn, lcn_end = prev_lcn + clus
If nEntry = 0 Then
If (lcn_start >= FRAG_START1 And lcn_start <= FRAG_END1) Or _
(lcn_end >= FRAG_START1 And lcn_end <= FRAG_END1) Then nEntry = 1
EndIf
If nEntry = 0 Then
If (lcn_start >= FRAG_START2 And lcn_start <= FRAG_END2) Or _
(lcn_end >= FRAG_START2 And lcn_end <= FRAG_END2) Then nEntry = 2
EndIf
If nEntry = 0 Then
If (lcn_start >= FRAG_START3 And lcn_start <= FRAG_END3) Or _
(lcn_end >= FRAG_START3 And lcn_end <= FRAG_END3) Then nEntry = 3
EndIf
EndIf
If FRAG_SHOW Or UnitIndex Then
sOut &= ' ' & StrFormat("%9u %12s", clus, SizeFormat(clus * nCluster * nSector, 1, "G", 2))
EndIf
vcn = next_vcn
If FRAG_SHOW Or UnitIndex Then
If FRAG_SHOW And i+2 > FRAG_LINES Then Break
sOut &= auCRLF & StrFormat("%3u %8u %12s", i+2, vcn, SizeFormat(lcn, 0, "B", 0, 2))
EndIf
Next
If FRAG_SHOW Or UnitIndex Then
SetHintParam("ShowHint", "Font", 9, "Consolas")
SetHintParam("ShowHint", "BackColor", 0x000000)
SetHintParam("ShowHint", "Text", 0xFFFFFF)
sDbg = nSysErr & auCRLF & "hFile=" & hFile & auCRLF & "bytes=" & Bytes & auCRLF
sHeader = "File: " & StrLeft(FileGetName(FileName),40) & auCRLF & _
"Volume: " & sVolume & auCRLF & _
"Sector: " & nSector & " bytes" & auCRLF & _
"Cluster: " & nCluster & " sectors" & auCRLF & _
"Free: " & nFree & " Total: " & nTotal & auCRLF & _
"Fragments: " & (contig > 0 ? c-contig & "/" : "") & c & _
" Clusters: " & (nSysErr = ERROR_MORE_DATA ? ">" : "") & last_vcn & _
" Size: " & SizeFormat(fs, 1, "G", 2) & auCRLF & _
"-------------------------------------------------" & auCRLF & _
" N VCN LCN Clusters Size " & auCRLF & _
"-------------------------------------------------"
sOut = (Dbg ? sDbg : "") & sHeader & auCRLF & sOut
If UnitIndex = 1 Then
ClipPut(sOut)
ShowHint(c & " фрагментов скопировано в буфер")
Sleep(200)
Else
ShowHint(sOut)
EndIf
Sleep(500)
SetHintParam("ShowHint", "Reload")
EndIf
If FRAG_NUM Then Return c
If FRAG_ENTRY = 2 Then Return nEntry
Return (nSysErr = ERROR_MORE_DATA ? ">" : "") & _
(contig > 0 ? c-contig & "/" : "") & c & (nEntry > 0 ? "*" & nEntry : "")
EndFuncКод кнопки стандартный. При желании номер команды можно заменить:
Код: Выделить всё
TOTALCMD#BAR#DATA
70400
%COMMANDER_EXE%
Кластеры файла|Ctrl - Скопировать в буфер
-1
FRAG_SHOW - просто глобальная переменная, которая используется внутренне. Ее первоначальное значение ни на что не влияет.
FRAG_LINES - количество строк в подсказке. Т.к. фрагментов может быть сотни и тысячи, размер посказки нужно как-то ограничивать.
FRAG_BUFFER - размер буфера в килобайтах. Это буфер, в который возвращается информация о фрагментах. Но поскольку фрагментов может быть очень много, всё в буфер может не влезть. В таких случаях рекомендуют делать повторные вызовы, но я не стал этим загоняться. При желании можно увеличить буфер, если нужно видеть большее количество записей. 32Кб дают где-то 2000 записей.
FRAG_NUM - если true, то в кастомное поле "Frag" будет выводится только числовой тип данных. По умолчанию это поле строковое и может содержать строку формата "1/3*2", где 1 - число реальных фрагментов, 3 - число записей в MFT, 2 - попадание во второй диапазон.
FRAG_ENTRY - если true, то в кастомное поле "Frag" будет попадать информация о вхождении в диапазон после звездочки.
FRAG_START1 и FRAG_START3 - начало и конец диапазона в кластерном пространстве. Информация о диапазоне также выводится в поле "FragEntry". Удобно, если нужно найти файлы, попадающие в ту или иную область на диске.
Поле "FragNum" содержит информацию только в числовом выражении.
Есть кое-какие ограничения в работе, но о них нужно отдельно написать. Завтра, по возможности, это сделаю.
Продолжение к вышестоящему посту.
Сейчас вижу, что есть некоторые недоработки, но в целом код рабочий. Это нормально, изначально не ставил задачи сделать всё идельно, хотелось просто посмотреть, что из этого выйдет.
Вообще, хотелось бы иметь инструмент, помогающий при работе с такими программами, как BadNTFS, и чтобы этот инструмент сразу был интегрирован в ТС и чтобы не возникало необходимости прибегать к сторонним утилитам типа DiskView, WinContig или того же Defraggler. Сейчас подсказка выводит информацию в таком виде:
Напоминает вывод консольной утилиты от Руссеновича Contig, но у Руссеновича не выводятся сведения о логическом номере кластера - LCN, хотя именно они в первую очередь и нужны при работе с плохими секторами на диске.
Немного об ограничениях. Про буфер уже говорилось. FRAG_BUFFER = 32 может получить информацию только о 2047 записях, т.к. размер буфера ограничен 32Кб. Когда буфера не хватает, функция возвращает код ERROR_MORE_DATA, соответственно в кастомном поле возможно пометить такие фрагменты знаком ">", указывающим, что фрагментов на самом деле больше, т.е. например ">2047". В подсказке это помечается в поле кластеров:
Чтобы получить правильные сведения о всех фрагментах, необходимо делать повторные вызовы, смещая стартовую точку, но я не стал этим загоняться. Как правило, сильно фрагментированных файлов не так много, и информацию он них можно получить в любой программе-дефрагментаторе, в том же Defraggler.
Еще один момент. Информация о VCN и LCN сохраняется в 64-битный юнион LARGE_INTEGER, который, по идее, надо было собрать назад функцией MakeInt, имеющейся в Autorun, но я не стал этим заморачиваться, считывая пока только старшую часть юниона. Это, как я понял, ограничивает LCN до 4Тб и на очень больших разделах может привести к неправильному отображению чисел.
Иногда в поле попадают такие записи, как "1/3" или "10/42" и т.д. Первое число - количество фрагментов на разделе. Второе - в файловой записи. Вероятно, это следствие работы программ-дефрагментаторов, которые после дефрагментации файла по какой-то причине не вносят изменения в запись, например:
Файл занимает одну сплошную область от 19 686 209 до 19 695 275, но, видимо, раньше он состоял из 3-х фрагментов, сведения о которых так и остались в его записи.
Ну вот пока и все. Для использования в наборе можно использовать поле "Frag", например [=tc.size.bkMGT2]\n[=autorun.Frag]. Для поиска или подсветки файлов можно создать шаблоны поиска, например: autorun.FragNum > 1000 или autorun.FragEntry = 1
Сейчас вижу, что есть некоторые недоработки, но в целом код рабочий. Это нормально, изначально не ставил задачи сделать всё идельно, хотелось просто посмотреть, что из этого выйдет.
Вообще, хотелось бы иметь инструмент, помогающий при работе с такими программами, как BadNTFS, и чтобы этот инструмент сразу был интегрирован в ТС и чтобы не возникало необходимости прибегать к сторонним утилитам типа DiskView, WinContig или того же Defraggler. Сейчас подсказка выводит информацию в таком виде:
Код: Выделить всё
File: autorun_20250805.zip
Volume: e:\
Sector: 512 bytes
Cluster: 8 sectors
Free: 1288683 Total: 15728698
Fragments: 4 Clusters: 87 Size: 347,64 Kb
-------------------------------------------------
N VCN LCN Clusters Size
-------------------------------------------------
1 0 15 327 813 9 36 Kb
2 9 14 170 518 15 60 Kb
3 24 14 102 396 32 128 Kb
4 56 12 671 977 31 124 Kb
5 87 0Немного об ограничениях. Про буфер уже говорилось. FRAG_BUFFER = 32 может получить информацию только о 2047 записях, т.к. размер буфера ограничен 32Кб. Когда буфера не хватает, функция возвращает код ERROR_MORE_DATA, соответственно в кастомном поле возможно пометить такие фрагменты знаком ">", указывающим, что фрагментов на самом деле больше, т.е. например ">2047". В подсказке это помечается в поле кластеров:
Код: Выделить всё
Fragments: 2047 Clusters: >239430 Size: 7,93 GbЧтобы получить правильные сведения о всех фрагментах, необходимо делать повторные вызовы, смещая стартовую точку, но я не стал этим загоняться. Как правило, сильно фрагментированных файлов не так много, и информацию он них можно получить в любой программе-дефрагментаторе, в том же Defraggler.
Еще один момент. Информация о VCN и LCN сохраняется в 64-битный юнион LARGE_INTEGER, который, по идее, надо было собрать назад функцией MakeInt, имеющейся в Autorun, но я не стал этим заморачиваться, считывая пока только старшую часть юниона. Это, как я понял, ограничивает LCN до 4Тб и на очень больших разделах может привести к неправильному отображению чисел.
Иногда в поле попадают такие записи, как "1/3" или "10/42" и т.д. Первое число - количество фрагментов на разделе. Второе - в файловой записи. Вероятно, это следствие работы программ-дефрагментаторов, которые после дефрагментации файла по какой-то причине не вносят изменения в запись, например:
Код: Выделить всё
Fragments: 1/3 Clusters: 9066 Size: 35,41 Mb
-------------------------------------------------
N VCN LCN Clusters Size
-------------------------------------------------
1 0 19 686 209 3792 14,81 Mb
2 3792 19 690 001 4832 18,87 Mb
3 8624 19 694 833 442 1,72 Mb
4 9066 0Ну вот пока и все. Для использования в наборе можно использовать поле "Frag", например [=tc.size.bkMGT2]\n[=autorun.Frag]. Для поиска или подсветки файлов можно создать шаблоны поиска, например: autorun.FragNum > 1000 или autorun.FragEntry = 1