Autorun

Обсуждение только плагинов и утилит для Total Commander.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Avada
Так это родной индикатор ТС? Тогда не удивительно, почему он так органично смотрится, особенно при изменениях размера окна и прочих перерисовках. :)

Loopback
Спасибо за наводку, попробую со Sleep и WinSetState. Видимо, получится.
Аватара пользователя
Avada
Сообщения: 10541
Зарегистрирован: Пт авг 01, 2008 16:17
Откуда: Россия, Саратов

Сообщение Avada »

Orion9
Да, это родной индикатор TC. Он же отображается, например, в правом углу окна синхронизации каталогов, если там что-то скрыто от показа (например, идентичные файлы) — с числом, сколько объектов скрыто. Качеством этот значок мог бы быть и получше, но Гислер давно уже потерял контакты с тем, кто ему-когда то рисовал значки, так что пытается справляться сам. И заменить значок нельзя...
Даже самая богатая фантазия
Не представит себе наши безобразия.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Avada
Да нормальный значок, мне нравится :)

Loopback
Все работает как вы и сказали, спасибо за подсказку!
Вряд ли. До времени подобных свистелок ещё далеко.
Да вы и так уже много сделали! А с новым функционалом возможностей стало еще больше. Я даже попробовать все не успел. Жаль, что сейчас времени уже не будет еще поизучать справку, но там действительно столько всего интересного прибавилось :)
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Пока не забыл: хотелось бы в будущем увидеть в справке пример для объекта Plugin, да и на дополнительные поля, если на то пошло. А то все как-то абстрактно и методом собственных проб и ошибок познается )
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9
Всё будет, но не сразу. Очень много времени на всё это нужно.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback
Примеры никогда не помешают, даже когда они кажутся совсем простыми. Но лучше, конечно, когда есть что-то более функциональное, что можно сразу применить в реальности, как, например, вот этот чёткий фрагмент кода:

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

RunThread ThreadFunction
 
Func ThreadFunction
    Local sPath, sName
    While 1
        sPath = RequestCopyDataInfo("SP")
        sName = RequestCopyDataInfo("SN")
        sPath = sPath & sName
        # выводим путь, просматривать можно с DebugView
        # выполнение цикла при этом не блокируется
        OutputDebugString("Autorun: Path = " & sPath)
        Sleep(1000) 
    Wend
EndFunc
Имхо, один из лучших примеров в справке. И отсылка к DebugView совершенно не лишняя. Думаю, что к объекту WMIQuery тоже не лишним будет указать какой-нибудь инструмент, типа SimpleWMIView, который значительно облегчает жизнь :)

Я всё-таки добил дополнительные поля. Классно вы сделали. Теперь есть возможность прямо из Autorun создавать и наполнять кастомные поля как хочется. Попробовал достать содержимое с помощью Autohotkey простеньким скриптом, и вот что получилось:

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

Pragma AutorunPluginFields "FileName:::GetTestValue" "DriveType:::GetTestValue" "FileSize:::GetTestValue"

Global AHKV2 = %COMMANDER_PATH% & "\Scripts\Ahk\AutoHotKey32.exe"

Func GetTestValue(FileName, FieldIndex, UnitIndex)
   Static pipe, _
          akh_fields = %COMMANDER_PATH% & "\Scripts\Ahk\Fields.ahk"
          
   Static file_name, file_size, drive_type          
          
   if FieldIndex = 1 then
      ProcessExecGetOutput pipe %AHKV2% '"%akh_fields%" "%FileName%"'
      
      file_name  = StrPart(pipe, auLF, 1)
      file_size  = StrPart(pipe, auLF, 3)
      drive_type = StrPart(pipe, auLF, 2)       
  
      return file_name
   endif
   
   if FieldIndex = 2 then return drive_type
   if FieldIndex = 3 then return SizeFormat(file_size, 1, "G", 2)

EndFunc
Сам ahk-скрипт вообще три строчки :)

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

#NoTrayIcon
FileAppend A_Args[1] "`n", "*"
FileAppend DriveGetType(A_Args[1]) "`n", "*"
FileAppend FileGetSize(A_Args[1]), "*"
Использовал возврат имени файла, чтобы убедиться, что юникодные имена корректно отрабатываются. Все норм. Скорость тоже рабочая (скорость даже удивила, я бы сказал). Удалось немного сократить количество вызовов AutoHotkey32.exe за счет статических переменных и строчной обработки stdout.

Экперемент удался, т.ч. теперь путь открыт :) Правда объекты я буду изучать теперь только в следующем семестре :mrgreen: Но справка, конечно, у вас шикарная. Говорю это еще раз, потому что до сих пор под впечатлением )

P.S. А ведь пульсар прикольный получился.) Сначала даже недооценил его (думал, больше шутка), но теперь вижу, что это очень удобная вещь! Захотел чуть понизить тона - жмешь Ctrl+"-", захотел повысить - Ctrl+"+". Когда тона начинают изменятся, повторно нажимаешь ту же комбинацию в нужный момент, и всё! Я даже подсел на это дело :mrgreen:

Добавлено спустя 25 минут:

Ooops... Маленькое уточнение: все-таки юникодные имена файлов корректно не возвращаются через ProcessExecGetOutput. Функция только поддерживает ANSI и OEM?
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

А ведь крутой функционал вы сделали для отладки! Одна OutputDebugString чего стоит! Так удобно стало и легко :)
Например, без проблем удалось подсчитать количество вызовов скрипта и общего числа входов в функцию, чтобы убедится, что все работает как надо:

[cut]

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

Func GetTestValue(FileName, FieldIndex, UnitIndex)
   Static pipe, _
          akh_fields = %COMMANDER_PATH% & "\Scripts\Ahk\Fields.ahk"
          
   Static file_name, file_size, drive_type, c = 0, f = 0 
   
   f = f + 1
          
   if FieldIndex = 1 then
      ProcessExecGetOutput pipe %AHKV2% '"%akh_fields%" "%FileName%"'
      
      file_name  = StrPart(pipe, auLF, 1)
      file_size  = StrPart(pipe, auLF, 3)
      drive_type = StrPart(pipe, auLF, 2)
      
      c = c + 1
      OutputDebugString("Autorun: f = " & f & " c = " & c)
  
      return file_name
   endif
   
   if FieldIndex = 2 then return drive_type
   if FieldIndex = 3 then return SizeFormat(file_size, 1, "G", 2)

EndFunc
[/cut]
А все переменные теперь можно посмотреть и вот так:

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

ControlSetMouseAction /L /B:7 17 AutorunStatus 0
ControlSetMouseAction /R /B:7 17 AutorunStatus 1

Func AutorunStatus(lParam)
Local vars

    vars = GetState("vars")

    if lParam = 1 then
       ClipPut(vars)
       ShowHint("Информация скопирована в буфер")
       Sleep(300)
       WinSetState(23)
    endif
    OutputDebugString(vars)
        
EndFunc
Но! Кажется, ClipPut обрезает текст, можете это подтвердить?

Перемнные в DebugView смотреть действительно удобно, и тут даже вспомнилось о Environment Variables Ex. А вот если в Autorun подобную фичу сделать для просмотра его внутреннего содержимого в виде wfx-функционала, или это уже лишним будет? :lol:

Еще пару моментов.

SetFieldsParam("OnDemand", 1) - только для строк по отдельности вызывается пробелом? А как можно сделать, чтобы все строки на странице обновлялись по требованию, или такого нет в ТС?

Ни WDX Guide, ни uwdx не отображают данные полей Autorun. С чем это связано? Ведь в наборе колонок все работает.

Кажется, WinSetState(21) не возвращает окно в доступное состояние. Но тут, правда, не уверен, надо еще проверять.
sa
Сообщения: 2758
Зарегистрирован: Ср апр 29, 2009 18:56

Сообщение sa »

Orion9 писал(а):WinSetState(21) не возвращает окно в доступное состояние.
Мне тоже когда-то показалось, что (20) и (21) перепутаны между собой.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):тоже не лишним будет указать какой-нибудь инструмент, типа SimpleWMIView
Для GetWMIValue указано :)
Orion9 писал(а):все-таки юникодные имена файлов корректно не возвращаются через ProcessExecGetOutput. Функция только поддерживает ANSI и OEM?
Судя по коду - да. Довольно странно, почему было сделано так. Нужно посмотреть, вроде ничего не мешает получить и юникод.
Orion9 писал(а):Одна OutputDebugString чего стоит!
Да, как-то про нее я подзабыл, давно надо было добавить.
Orion9 писал(а):Кажется, ClipPut обрезает текст, можете это подтвердить?
Посмотрю.
Orion9 писал(а):или это уже лишним будет
Пожалуй :)
Orion9 писал(а):или такого нет в ТС
Такого нет.
Orion9 писал(а):Ни WDX Guide, ни uwdx не отображают данные полей Autorun. С чем это связано? Ведь в наборе колонок все работает.
Странно, проверю.
Orion9 писал(а):Кажется, WinSetState(21) не возвращает окно в доступное состояние.
Кажется что-то было, но вроде уже было исправлено, в пока не выложенной версии.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Для GetWMIValue указано :)
Вы за 15 лет такую справку замутили, что тут не один день понадобится, чтобы всю ее изучить. Я туда еще тупо не дошел :lol: Но сейчас открыл - да, класс, еще и с примерами ))

Почти сбылась моя мечта, осталось только дату изменения файла вытащить, даже удивился, что нет для этого функции в новом наборе :lol:

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

ControlSetHint /F /D:50 /B:7 17 "HintFunc"
 
Func HintFunc()
   Local A_Version, A_Copyright, A_DateTime, A_Wdx = AUTORUN_PATH & "\Autorun.wdx"

   If IsPressed (0x10) Then Return GetState("libs")
   If IsPressed (0x11) Then Return GetState("threads") & auCR & GetState("procs")
   
   A_Version   = FileGetVersion(A_Wdx, "FileVersion")
   A_Copyright = FileGetVersion(A_Wdx, "LegalCopyright")
   A_DateTime  = FileGetTime(A_Wdx)
   
   Return "Версия: " & A_Version & auCR & "Авторские права: " & A_Copyright & auCR & "Дата изменения: " & A_DateTime

   Return GetState("paths")
EndFunc
Как отформатировать FileGetTime() средствами самого Autorun?
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Поскольку функции как отформатировать timestamp я не нашел, пришлось-таки пройти ускоренный курс по объектам :mrgreen:

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

Func HintFunc()
   Local A_Version, A_Copyright, A_DateTime, A_Wdx = AUTORUN_PATH & "\Autorun.wdx"

   If IsPressed (0x10) Then Return GetState("libs")
   If IsPressed (0x11) Then Return GetState("threads") & auCR & GetState("procs")
   
   A_Version   = FileGetVersion(A_Wdx, "FileVersion")
   A_Copyright = FileGetVersion(A_Wdx, "LegalCopyright")
   
   obj = Plugin("FileDateTime")
   if ERROR = 0 then
      obj.FileName = A_Wdx
      A_DateTime = StrFormat("%.0f", obj.GetValue(3))
      Free(obj)
   else
      A_DateTime = "Error " & ERROR
   endif

   Return "Версия: " & A_Version & auCR & "Дата изменения: " & A_DateTime & auCR & "Авторские права: " & A_Copyright 

EndFunc
Вот это другое дело. Вот это я понимаю, мощь какую вы сделали страшную! 🔥♥️

В идеале, хотелось бы еще увидеть в этой подсказке сводную статистику по плагину, типа:

Потоков запущено: 2
Загружено библиотек: 5
Подключенных модулей: 7
(...)

Было бы супер, если бы такая информация хранилась в объекте-массиве :)
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):Вы за 15 лет такую справку замутили, что тут не один день понадобится, чтобы всю ее изучить.
Если что, последнее время справка делается в соавторстве. Она бы в любом случае была, но вряд ли такого качества :)
Orion9 писал(а):Как отформатировать FileGetTime() средствами самого Autorun?
Наверно так?

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

Date("", A_DateTime) & " " & Time ("", A_DateTime)
Формат настраивается, естественно.
Orion9 писал(а):Поскольку функции как отформатировать timestamp я не нашел,
Похоже справка не так уж хороша? :wink:

А так, нуу... можно и так, конечно :)
Orion9 писал(а):сводную статистику по плагину
По моему мнению совершенно избыточная информация, не дающая ничего к функциональности. Да и не факт, что это в принципе можно реализовать в разрезе отдельной библиотеки, даже если бы вдруг захотелось сделать.

Если очень нужно, импорт/экспорт можно посмотреть плагином FileInfo или подобным.

Добавлено спустя 3 минуты:
Loopback писал(а):Кажется, ClipPut обрезает текст, можете это подтвердить?
Да, проблема есть, причем более глобальная, не только с ClipPut. Спасибо, исправлю.
Loopback писал(а):Ни WDX Guide, ни uwdx не отображают данные полей Autorun. С чем это связано? Ведь в наборе колонок все работает.
Проверил, всё везде показывается...
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback писал(а):Похоже справка не так уж хороша? :wink:
Да не, дело было не в бомбине :mrgreen: Но приведенный вами примерчик не помешал бы. Надеюсь, возьмете на будущее к сдедующим компиляциям справки :wink:
Loopback писал(а):А так, нуу... можно и так, конечно :)
Мы легких путей не ищем )
Loopback писал(а):По моему мнению совершенно избыточная информация, не дающая ничего к функциональности.
Ну, это вы зря. Пользу от такой статистики я усвоил еще со второго терминатора :mrgreen:
Loopback писал(а):Если очень нужно, импорт/экспорт можно посмотреть плагином FileInfo или подобным.
Да дело не в этом. Интересно, что там крутится-вертится в фоне, когда Autorun работает. Подробности вы сделали (GetState), а вот обобщенных данных нет.
Loopback писал(а):Проверил, всё везде показывается...
Завтра посмотрю. Скорее всего опять проблема с пробелами в путях. Другого объяснения пока нет.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Говоря о терминаторах... Изменил немного код:

[cut]

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

Func SetPulsar(nParam)
local a, b, s, l
static t = 0
   
   if Pulsar = 1 then 
      Pulsar = 0
      Return
   endif
   
    Pulsar = 1
   
   if nParam = 1 then 
      a = 1
      b = 2
      s = 1
   else
      a = 2
      b = 1
      s = -1
   endif
  
   While Pulsar = 1
   
      For j = a To b step s
      
         For i = 1 To 75
             
             SetBackGround(j)
             Sleep(25)
             l = l + 1
             t = t + 1
             
             if Pulsar = 0 then Break
             
             If IsPressed (0x1B) Then
                Pulsar = 0
                Break
             endif
             
         Next
         
         if Pulsar = 0 then Break
      Next
      
   Wend
   ShowHint("Изменений тонов: " & l & auCRLF & "Всего изменений: " & t)
   Sleep(1000)
   WinSetState(23)
EndFunc 
[/cut]
Вот теперь точно работает, как SkyNet прописала :mrgreen:

А вы говорите нет пользы от статистики ))

Ну а если серьезно, то кроме декоративно-информативных функций, теоретически, например, может потребоваться принимать решение о запуске (не запуске) потока в зависимости от количества уже запущенных потоков. Да и вообще: мало ли, что может еще пригодиться.

По поводу полей. Проверил на двух системах и на разных путях (без пробелов) - проблема та же: нет данных полей, хотя сами поля отображаются.

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

All columns:

[0] -> Autorun (Int32)
[1] -> FileName (UnicodeString)
[2] -> DriveType (UnicodeString)
[3] -> FileSize (UnicodeString)

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

All column values:

Autorun                         :
FileName                        :
DriveType                       :
FileSize                        :
Не знаю, в чем может быть проблема. Жаль, что вы ее не можете воспроизвести. Ну и ладно. Главное, что в колонках все работает.

Добавлено спустя 3 минуты:

WDX Guide, кстати, у меня вообще стал зависать при выборе плагина Autorun, хотя до этого тоже были пустые поля.

Добавлено спустя 56 минут:

Поменял тип данных у всех полей на ft_string:

Pragma AutorunPluginFields "FileName::ft_string:GetTestValue" "DriveType::ft_string:GetTestValue" "FileSize::ft_string:GetTestValue"

Упростил функцию до входа-выхода (return "text"), всё-равно та же проблема. WDX Guide виснет через раз, а когда не виснет - поля пустые, только в первом поле "Autorun" Value=ft_nosuchfield

При этом остальные плагины (даже WinScriptAdv, который тоже вызывает Autohotkey) все нормально.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):Не знаю, в чем может быть проблема. Жаль, что вы ее не можете воспроизвести. Ну и ладно. Главное, что в колонках все работает.
Это я неправильно понял, думал речь просто про получение информации о полях (название, тип).

А причина проблемы легко объяснима: скрипт работает в отдельном потоке, причём ему нужно время чтобы загрузиться. Поэтому, например, uwdx проходит по полям, но они ничего не возвращают, потому что поток, обеспечивающий работу привязанных функций ещё полностью не загрузился.

Получается, это принципиальное ограничение, изменить это нельзя. Autorun как wdx не получиться использовать из внешних утилит. Надо этот момент будет упомянуть в справке.
Ответить