Страница 198 из 243

Добавлено: Пн авг 11, 2025 11:51
Loopback
AkulaBig
Ясно.

Ну а я установил 24H2, но это ничего не дало (ожидаемо). Видимо, какие-то особенности вашей системы. Код ThreadWatchLang просмотрел, но опять же, нечего подозрительного не вижу. Куда копать в данный момент идей нет.

Могу пока сделать фикс положения, вот только тогда ошибка замаскируется. Или можно выводить окно где-то в углу, чтобы и читалось, и сразу было ясно, что опять вылез косяк.

Добавлено: Пн авг 11, 2025 16:23
AkulaBig
Loopback писал(а):Ну а я установил 24H2, но это ничего не дало (ожидаемо)
Очень странно. Попробую еще в Песочнице. Чище оськи не найдешь.
Loopback писал(а):Или можно выводить окно где-то в углу, чтобы и читалось, и сразу было ясно, что опять вылез косяк.
Может просто выводить по центру экрана, а не ТС? И еще ведь не надо забывать, что только эта ошибка у меня автозакрывается. Даже на ТС32.

Добавлено: Пн авг 11, 2025 16:35
jentoso
AkulaBig писал(а):Может просто выводить по центру экрана, а не ТС?
А потом не возникнут проблемы с тем, что у кого-то два и более мониторов и определять куда именно выводить, отлично от центра самого TC?

Добавлено: Пн авг 11, 2025 18:01
AkulaBig
Loopback
Попробовал в Песочнице. Никаких изменений. Так что даже представить не могу, почему у вас ошибка не срабатывает. Включите Песочницу. Чудес ведь не бывает. Должно одинаково работать.
jentoso писал(а):А потом не возникнут проблемы с тем, что у кого-то два и более мониторов и определять куда именно выводить, отлично от центра самого TC?
Вообще Винда сама отслеживает вроде-бы, но настройками можно изменить.

Добавлено: Пн авг 11, 2025 20:55
Loopback
AkulaBig писал(а):Может просто выводить по центру экрана, а не ТС?
AkulaBig писал(а): что только эта ошибка у меня автозакрывается. Даже на ТС32.
Это самое простое, просто тогда будет непонятно, что произошёл сбой. Впрочем, раз окно самозакрывается, то вообще никакой разницы.

В принципе окно у меня тоже иногда закрывалось, но только под x64, это другой, старый недолеченный баг. В 32-битной ни разу. При этом отладочный вывод нормальный, так что это не та проблема.
AkulaBig писал(а):Включите Песочницу.
Песочница не хочет ставиться на гостевой системе. Но в этом, думаю, нет необходимости, потому что система только что была развернута и обновлена, совершенно чистая.
AkulaBig писал(а):Чудес ведь не бывает.
О, ещё как бывают. Иначе бы все баги всегда повторялись.

Добавлено: Ср авг 20, 2025 08:22
AkulaBig
Loopback
Как создать переменную в текущем пользователе, а не в текущем процессе? Только через cmd?

Добавлено: Ср авг 20, 2025 10:07
Loopback
AkulaBig
Переменные окружения пользователя хранятся в разделе реестра "HKEY_CURRENT_USER\Environment". Нужно туда добавить ключ.

В разделе примеров "Разное" в справке есть пример "Добавление каталога в PATH", можно его за основу взять.

Добавлено: Ср авг 20, 2025 12:11
AkulaBig
Loopback писал(а):Нужно туда добавить ключ
Я так сделал:

Код: Выделить всё

ShellExec /SW_HIDE /WAIT %COMSPEC% '/c setx OIT_DATA_PATH C:\'
Нормально работает.

Добавлено: Вт сен 02, 2025 06:47
yahuu
Системный формат времени: 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

Добавлено: Вт сен 02, 2025 10:20
Loopback
yahuu
Да, подтверждаю.

Добавлено: Вт сен 02, 2025 11:04
Orion9
Loopback
Autorun 2.2.19.1, пример из справки ["Синтаксис" -> "Функции"] не работает?

Код: Выделить всё

Local sysdir
DllCall("GetSystemDirectoryW", "wstr:256", @sysdir, "int", 255)

Добавлено: Вт сен 02, 2025 19:40
Loopback
Orion9
В 2.2.19.1 нет, не работает, исправлено в этой.

Добавлено: Вт сен 02, 2025 23:40
Orion9
Loopback
Вот что значит быстро читать. Просмотрел этот момент. Не ожидал, что будет так много сообщений за время моего отсутствия, пришлось ускориться. Но обновленную версию видел и скачал, просто подумал, что она связана с багофиксами, которые обсуждались, и как-то не вкурил я в эту фразу: "регресс с версии 2.2.17" :lol:

В общем, хотел использовать эту фичу в вызове 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
[/cut]
Код кнопки стандартный. При желании номер команды можно заменить:

Код: Выделить всё

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" содержит информацию только в числовом выражении.

Есть кое-какие ограничения в работе, но о них нужно отдельно написать. Завтра, по возможности, это сделаю.

Добавлено: Ср сен 03, 2025 13:04
Orion9
Продолжение к вышестоящему посту.

Сейчас вижу, что есть некоторые недоработки, но в целом код рабочий. Это нормально, изначально не ставил задачи сделать всё идельно, хотелось просто посмотреть, что из этого выйдет.

Вообще, хотелось бы иметь инструмент, помогающий при работе с такими программами, как 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
Напоминает вывод консольной утилиты от Руссеновича Contig, но у Руссеновича не выводятся сведения о логическом номере кластера - LCN, хотя именно они в первую очередь и нужны при работе с плохими секторами на диске.

Немного об ограничениях. Про буфер уже говорилось. 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
Файл занимает одну сплошную область от 19 686 209 до 19 695 275, но, видимо, раньше он состоял из 3-х фрагментов, сведения о которых так и остались в его записи.

Ну вот пока и все. Для использования в наборе можно использовать поле "Frag", например [=tc.size.bkMGT2]\n[=autorun.Frag]. Для поиска или подсветки файлов можно создать шаблоны поиска, например: autorun.FragNum > 1000 или autorun.FragEntry = 1

Добавлено: Ср сен 03, 2025 13:40
A55555
Здравствуйте.

При помощи данного плагина можно сделать выключение ПК после окончания копирования в TC?