Autorun

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

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

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

Сообщение Orion9 »

Loopback писал(а):Насчет лучший не знаю, можно, конечно и с имеющимися функциями написать, учитывая переполнение, но считаться трафик будет от запуска тотала.
Да, я думал об этом. Именно поэтому решил делать через WMI, так как нужен полный объем трафика. Но надо будет ещё подумать, что делать с интерфейсом. А пока - простая реализация планировщика заданий на Autorun! :D

Окно монитора заданий вызывается при наведении на заголовок.

[cut="usercmd.ini"]

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

[em_update_wdx_menu]
cmd=90000
param=

[em_change_lang_ru]
cmd=OPENLANGUAGEFILE
param=WCMD_RUS.LNG

[em_change_lang_en]
cmd=OPENLANGUAGEFILE
param=WCMD_ENG.LNG
[/cut]
[cut="Schedule.ini"]

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

;     ключ - команда задания
; значение - интервал выполнения задания (не меньше 20 сек.)
;          - задержка перед первым выполнением (не меньше 10 сек.)
;          - количество повторений задания, включая первое выполнение (не меньше одного)
;          - ссообщение в заголовке
[Schedule]
em_update_wdx_menu=180,10,2,Updating Wdx Array
em_change_lang_en=20,15,3,Changing Language En
em_change_lang_en=20,,Changing Language En
em_change_lang_ru=30,25,10,Changing Language Ru
em_change_lang_ru=30,5,10,Testing
[/cut]
[cut="Test.aucfg"]

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

RegisterCommand 90000 ScheduleTest1

Func ScheduleTest1(lParam)
    MsgBox("Выполнение команды по расписанию")
EndFunc

Global Div = "  > "
Global TitleSeconds = 0, TitleBreak = false
Global JustTitle = WinGetText(), VarTitle = JustTitle

Global IniFile = %COMMANDER_PATH% & "\Ini\Schedule.ini"

Global aUserCmd = List(), aUserInterval = List()
Global aUserDelay = List(), aUserRepeat = List(), aUserMsg = List()
Global aUserDone = List(), aUserProx = List()

ControlSetHint /F /D:300 /H:2 0 "GetSchedule"

LoadSchedule()

RunThread ThreadSchedule

Func ThreadSchedule()
    While 1
       VarTitle = JustTitle & Div & "Memory: " & GetMemStats(0) & "%  CPU: " & GetCPUUsage() & "%"
       UpdateSchedule()
       WinSetText(VarTitle)
       Sleep(1000)
       TitleSeconds += 1
    Wend
EndFunc

Func LoadSchedule()
    Local bad, item
    Local sect, j, aSect = List()
    # чтение секции
    sect = IniReadSection(IniFile, "Schedule")
    aSect.Text = sect
    # сброс массивов
    aUserCmd.Count = 0
    aUserInterval.Count = 0
    aUserDelay.Count = 0
    aUserRepeat.Count = 0
    aUserMsg.Count = 0
    aUserDone.Count = 0
    aUserProx.Count = 0
    # в секции нет записей
    If aSect.Count = 0 Then Return    
    # заполнение массивов
    For j = 0 To aSect.Count - 1
        If StrPos(aSect[j], "=") > 0 Then
           bad = false
           # ключ
           key = StrPart(aSect[j], "=", 1)
           # значение
           val = StrPart(aSect[j], "=", 2)
           # em_команда задания
           aUserCmd.Add(key) 
           # интервал выполнения задания
           item = StrPart(val, ",", 1)
           If Not IsInt(item) Or item < 20 Then
              bad = true
              item = "-"
           EndIf
           aUserInterval.Add(item)   
           aUserProx.Add(item)                    
           # задержка перед первым выполнением
           item = StrPart(val, ",", 2)           
           If Not IsInt(item) Or item < 10 Then
              bad = true
              item = "-"              
           EndIf           
           aUserDelay.Add(item)
           # количество вылолненных
           aUserDone.Add(0)             
           # количество повторений задания
           item = StrPart(val, ",", 3)           
           If Not IsInt(item) Or item < 0 Then
              bad = true
              item = "-"              
           EndIf                      
           aUserRepeat.Add(item)     
           # сообщение в заголовок
           item = StrPart(val, ",", 4)           
           If item = "" Then
              item = key
           EndIf        
           # проверка корректности записи
           If bad Then
              item = "# Incorrect"
              aUserInterval[j] = "-"
              aUserProx[j] = "-"              
              aUserDelay[j] = "-"
              aUserRepeat[j] = "-"
           EndIf                                       
           aUserMsg.Add(item)    
        EndIf         
    Next
    Free(aSect)
EndFunc

Func GetSchedule()
    Local txt, j, state     
    txt = "Виртуальная память: " & GetMemStats(1) & auCRLF     
    for i = 3 to 6
        #txt &= "GetMemStats(" & i & ") = " & StrFormat("%.0f", GetMemStats(i) / 1048576) & auCRLF
    next     
    txt &= "Планировщик заданий, всего циклов: " & TitleSeconds & auCRLF
    txt &= "-----------------------------------------------------------------------------------------" & auCRLF    
    txt &= "Задание №" & auTAB & "Команда / Сообщение" & auTAB & "Инт." & auTAB & "Перв." & auTAB & _
           "Повт." & auTAB & "Выпол." & auTAB & "След." & auTAB & "Состоян." & auCRLF
    txt &= "-----------------------------------------------------------------------------------------" & auCRLF
    For j = 0 To aUserCmd.Count - 1
        state = (aUserDone[j] = aUserRepeat[j] ? "Завершено" : "Работает")   
        If aUserInterval[j] = "-" Then state = "-"
        txt &= "Задание №" & j+1 & auTAB & StrFormat("%-20.20s", aUserMsg[j]) & auTAB & aUserInterval[j] & auTAB & _
                aUserDelay[j] & auTAB & aUserRepeat[j] & auTAB & aUserDone[j] & auTAB & aUserProx[j]  & auTAB & state & auCRLF
    Next
    # стиль подсказки
    SetHintParam("csh", "Font", 9, "Consolas")
    #SetHintParam("csh", "Font", 9, "Arial")    
    SetHintParam("csh", "BackColor", 0x00000000)
    SetHintParam("csh", "Text", 0xFFFFFF)    
    # вернуть предыдущий стиль через 1 сек.
    RunThread HintParamReload
    # текст подсказки
    Return StrTrim(txt)    
EndFunc

Func HintParamReload()
    Sleep(1000)
    SetHintParam("csh", "Reload")      
EndFunc

Func UpdateSchedule()
    Local prox, j
    Local send, msg = false
    For j = 0 To aUserCmd.Count - 1
        # флаг выполнения задания        
        send = false
        # некорректная запись
        If aUserRepeat[j] = "-" Then Continue        
        # задание завершено
        If aUserDone[j] = aUserRepeat[j] Then Continue
        # задание ещё не выполнялось
        If aUserDone[j] = 0 Then  
           # задержка перед первым выролнением  
           If aUserDelay[j] - TitleSeconds < 3 Then 
              # локальный флаг           
              msg = true
              # глобальный флаг              
              TitleBreak = true
              # сообщение в заголовке              
              VarTitle = Div & "Usercmd" & Div & aUserMsg[j] & "..."        
           EndIf
           If aUserDelay[j] = TitleSeconds  Then send = true
        # задание ранее выполнялось
        Else
           # проверка состояния счётчика
           If aUserProx[j] = "-" Then Continue
           # отсчет до следующего выполнения
           prox = aUserProx[j] - 1
           # близость выполнения
           If prox < 3 Then
              msg = true
              TitleBreak = true
              VarTitle = Div & "Usercmd" & Div & aUserMsg[j] & "..."
           Endif
           # выполнение задания
           If prox = 0 Then 
              # сброс счётчика к новому интервалу
              prox = aUserInterval[j]
              # флаг выполнения задания
              send = true
           Endif   
           aUserProx[j] = prox
        EndIf 
        # флаг выполнения        
        If send Then
           # количество выполненных  
           aUserDone[j] = aUserDone[j] + 1
           # все повторы выполнены
           If aUserDone[j] = aUserRepeat[j] Then aUserProx[j] = "-" 
           # посылка команды задания
           CommandExec(aUserCmd[j])           
        EndIf   
    Next 
    # смена сообщения в заголовке
    If msg Then
       VarTitle = JustTitle & VarTitle
    Endif
EndFunc
[/cut]
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Важное объявление

В ближайшей паре версий будут сделаны существенные изменения, которые, возможно, повлекут за собой неработоспособность некоторых записей в скриптах.

Первый этап

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

Перестанет работать код в функциональной записи, который основывался на разворачивании переменных прямо в тексте:

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

Например
FileGetAttr("%COMMANDER_PATH%\Totalcmd.exe")
нужно заменить на 
FileGetAttr(COMMANDER_PATH & "\Totalcmd.exe")
или
FileGetAttr(Set("%COMMANDER_PATH%\Totalcmd.exe"))
Если текст с %переменной% содержится в другой переменной и раньше код основывался на разворачивании этого текста в параметре функции, то теперь в функциональной записи разворачивание производиться не будет. Чтобы достичь такого же результата, нужно будет добавить Set для явного разворачивания содержимого переменной:

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

path = "%COMMANDER_PATH%\Totalcmd.exe"
Было
FileGetAttr(path)
стало
FileGetAttr(Set(path))
Переключатель /EV-, встречающийся в ряде функций, теперь будет неприменим при записи в ФЗ.

Все записи функций в командном виде должны сохранить работоспособность без изменений.

Второй этап

Также, как следствие из первого этапа, было принято решение оптимизировать синтаксис и избавить его от некоторых послаблений и допущений, которые были сделаны в ранних версиях, что, в частности, позволит более чётко разграничить записи в КЗ и ФЗ.
  • Будет убрана возможность использовать переменные в виде %var% в выражениях, их использование будет ограничено только командной записью функций.
  • Будет убрана директива LegacyExpressions.
Это будет сделано не в ближайшей версии, а скорее всего через одну. Но вносить изменения можно уже сейчас, для этого просто нужно заменить в выражениях (в том числе в вычисляемых строках) использование вида переменных %var% на var. Это означает примерно такое:

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

var = %COMMANDER_PATH% & "\Totalcmd.exe"
должно стать
var = COMMANDER_PATH & "\Totalcmd.exe"

len = StrLen(%var%)
должно стать
len = StrLen(var)

ShowHint %"%var%"
должно стать
ShowHint %"var"
Подчеркиваю, только в выражениях. В строках с командной записью менять нужно только содержимое вычисляемых строк.

Найти переменные легко с помощью регулярных выражений, выполняя замену где необходимо.

По поводу LegacyExpressions - думаю, вряд ли ещё остался кто-то, использующий старую интерпретацию.
Последний раз редактировалось Loopback Вс мар 02, 2025 23:45, всего редактировалось 1 раз.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Кто сказал, что у Autorun нет своей иконки в трее? :mrgreen:

[cut]

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

SetMessageAction /P 55555 TrayAction

Func TrayAction(hWnd, uMsg, wParam, lParam)
    If lParam = 0x0204 Then
       AutorunMenu(0)
    Elseif lParam = 0x0201 Then
        ShowHint(GetState("libs"))
    EndIf   
EndFunc

TrayIcon()

Func TrayIcon()
    Local i = 0, _
          f = %COMMANDER_PATH% & "\TOTALCMD.EXE", _
          file, hint, _
          hIco = 0          
    #i = 15
    #f = GetKnownFolderPath("System") & "\shell32.dll"
    
    file = Buffer(StrLen(f)*2+2) 
    file.SetStr(f & Chr(0))
    
    hIco = DllCall("shell32\ExtractIconW", "ptr", AUTORUN_TCHANDLE, "ptr", file.Ptr, "uint", i, "ptr")        
    Free(file)
    
    hint = "Autorun " & FileGetVersion(AUTORUN_PATH & "\Autorun.wdx", "FileVersion")
    NotifyIconAdd(1001, 55555, hIco, hint)
    If hIco > 0 Then DllCall("DestroyIcon", "ptr", hIco, "bool")        
EndFunc

Func NotifyIconAdd(ID, CallbackMessage, hIcon, Tip)
    Local NIF_MESSAGE = 0x00000001, _
          NIF_ICON    = 0x00000002, _
          NIF_TIP     = 0x00000004, _
          TIP_MAXCHAR = 128 - 1
    Local buf = Buffer((auPtrSize = 4 ? 956 : 976))
    buf.Zero()
    buf.SetNum(0, "dword", buf.size, _   
                  "ptr", AUTORUN_TCHANDLE, _         
                  "uint", ID, _
                  "uint", BitOR(NIF_MESSAGE, NIF_ICON, NIF_TIP), _
                  "uint", CallbackMessage, _
                  "ptr", hIcon)        
    buf.SetStr(StrLeft(Tip, TIP_MAXCHAR) & Chr(0), auPtrSize*2 + 4*4)
    Return DllCall("Shell32.dll\Shell_NotifyIconW", "uint", 0, "ptr", buf.ptr, "bool")
EndFunc
[/cut]
[cut]Код функции AutorunMenu в модуле Modules.aucfg на предыдущих страницах[/cut]
Loopback, нет ли здесь ошибок явных или неявных? А то у меня нет полной уверености. Делал по структуре:
https://learn.microsoft.com/en-us/windo ... yicondataw

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

Сообщение Loopback »

Orion9
Сначала написал что всё в порядке, но как обычно забыл проверить на x64. На ней функция не работает по причине неправильных смещений. К сожалению, в структурах есть такая неприятная вещь, как выравнивание полей, из-за чего не всегда смещение следующего поля будет равно смещению текущего + его размер.

В связи с чем инициализация под x64 должна выглядеть по-другому:

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

Func NotifyIconAdd(ID, CallbackMessage, hIcon, Tip)
    Local NIF_MESSAGE = 0x00000001, _
          NIF_ICON    = 0x00000002, _
          NIF_TIP     = 0x00000004, _
          TIP_MAXCHAR = 128 - 1
    Local buf = Buffer((auPtrSize = 4 ? 956 : 976))    
    buf.Zero()
    If auX64 Then
        buf.SetNum(0,  "dword", buf.size)
        buf.SetNum(8,  "hwnd", AUTORUN_TCHANDLE)
        buf.SetNum(16, "uint", ID, _
                       "uint", BitOR(NIF_MESSAGE, NIF_ICON, NIF_TIP), _
                       "uint", CallbackMessage)
        buf.SetNum(32, "ptr", hIcon)
    Else
        buf.SetNum(0, "dword", buf.size, _   
                      "hwnd", AUTORUN_TCHANDLE, _         
                      "uint", ID, _
                      "uint", BitOR(NIF_MESSAGE, NIF_ICON, NIF_TIP), _
                      "uint", CallbackMessage, _
                      "ptr", hIcon)  
    EndIf

    buf.SetStr(StrLeft(Tip, TIP_MAXCHAR) & Chr(0), (auX64 ? 40 : 24)) # auPtrSize*2 + 4*4
    Return DllCall("Shell32.dll\Shell_NotifyIconW", "uint", 0, "ptr", buf.ptr, "bool")
EndFunc
Еще, для передачи имени файла буфер не нужен, всё необходимое есть в DllCall:

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

Func TrayIcon()
    Local i = 0, _
          f = %COMMANDER_PATH% & "\TOTALCMD.EXE", _
          file, hint, _
          hIco = 0         
    #i = 15
    #f = GetKnownFolderPath("System") & "\shell32.dll"
   
    hIco = DllCall("shell32\ExtractIconW", "ptr", AUTORUN_TCHANDLE, "wstr", f, "uint", i, "ptr")
   
    hint = "Autorun " & FileGetVersion(AUTORUN_PATH & "\Autorun.wdx", "FileVersion")
    NotifyIconAdd(1001, 55555, hIco, hint)
    If hIco > 0 Then DllCall("DestroyIcon", "ptr", hIco, "bool")       
EndFunc
Да, и еще надо иконку скрывать перед выходом ТС, иначе в трее остаётся болтаться. Ну и buf в функции надо освобождать (или в static его).
Orion9 писал(а):Только регулярками там скорее всего не обойтись, всё-равно придётся код построчно просматривать
Конечно же не имелось в виду, что всё подряд заменять, пройтись внимательно с поиском и заменой.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback
Спасибо за уточнения!

Я тоже сразу не догадался проверить в TC x64, но потом обнаружил, что там ничего не работает, т.е. в трее иконка не появляется. Но хорошо, что вы всё поправили и объяснили. Сколько всяких сложностей-то. Это тебе не хухры-мухры :D

Кстати, по поводу сетевого интерфейса. Как вариант, можно сделать выбор из меню.

На основе вашего примера в справке GetDriverList:

[cut]

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

Global NetworkInterface
Global aNetworkInterfaces = List()
RegisterCommand 80010 "GetNetworkInterface"

RegisterCommand 80011 "SetNetworkInterface" 1
RegisterCommand 80012 "SetNetworkInterface" 2
RegisterCommand 80013 "SetNetworkInterface" 3
RegisterCommand 80014 "SetNetworkInterface" 4
RegisterCommand 80015 "SetNetworkInterface" 5

Func GetNetworkInterface(lParam)
    Runthread GetNetworkInterfaceList
EndFunc

Func GetNetworkInterfaceList()
    Local wq = WMIQuery()     
    wq.Query('SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface')     
    aNetworkInterfaces.Count = 0     
    While wq.Next()
       aNetworkInterfaces.Add(wq.GetValue("Name"))
    Wend
    Free(wq)   
    If aNetworkInterfaces.Count = 0 Then
       MsgBox("Не найден сетевой интерфейс", "NetworkInterface", 48)
       Return
    EndIf
    ShowPopupMenu /D /F "NetworkInterfacesMenu"   
EndFunc

Func NetworkInterfacesMenu()
    Local i, txt
    For i = 0 To aNetworkInterfaces.Count - 1    
       txt = txt & 'MENUITEM "' & aNetworkInterfaces[i] & '\t' & i & '", 800' & 11+i & auCRLF      
    Next
    txt = txt & 'MENUITEM SEPARATOR' & auCRLF
    txt = txt & 'MENUITEM "Обновить", 80010' & auCRLF    
    Return txt
EndFunc

Func SetNetworkInterface(lParam, nItem)
    NetworkInterface = aNetworkInterfaces[nItem - 1]
    MsgBox("Cетевой интерфейс - " & NetworkInterface, "NetworkInterface", 64)
EndFunc
[/cut]
А потом в запросе имя переменной NetworkInterface подставлять. Но это я еще не успел доделать.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback писал(а):К сожалению, в структурах есть такая неприятная вещь, как...
Для неискушённого пользователя "сюрпризов" там хватает ) Например, не понятно, нужно ли самому считать размер структуры или где-то есть уже готовые таблицы, типа:
[cut]

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

; typedef struct tagCHOOSECOLORW {  offset      size    (x86/x64)
  ; DWORD        lStructSize;       |0      |   4
  ; HWND         hwndOwner;         |4 / 8  |   8 /16
  ; HWND         hInstance;         |8 /16  |   12/24
  ; COLORREF     rgbResult;         |12/24  |   16/28
  ; COLORREF     *lpCustColors;     |16/28  |   20/32
  ; DWORD        Flags;             |20/32  |   24/36
  ; LPARAM       lCustData;         |24/40  |   28/48 <-- padding for x64
  ; LPCCHOOKPROC lpfnHook;          |28/48  |   32/56
  ; LPCWSTR      lpTemplateName;    |32/56  |   36/64
  ; LPEDITMENU   lpEditInfo;        |36/64  |   40/72
; } CHOOSECOLORW, *LPCHOOSECOLORW;
[/cut]
Фрагмент из скрипта AutoHotkey для вызова системного диалога "Выбор цвета". Видимо, автор всё-таки сам делал этот расчёт, поскольку выравнивание (paddiing), если я правильно понимаю, указано неверно :)

Попробовал сделать на Autorun этот вызов:
[cut]

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

# системный диалог выбора цвета
RegisterCommand 70052 "ColorSelect"

Func ColorSelect(lParam)    
    Local cls = Buffer(64), buf = Buffer(auX64 ? 72 : 36)
    cls.Zero()
    cls.SetNum(0, "dword", 0x000000FF, _
                  "dword", 0x0000FF00, _
                  "dword", 0x00FF0000, _
                  "dword", 0x00808080)
    buf.Zero()                    
    If auX64 Then
        buf.SetNum(0,  "dword", buf.size)
        buf.SetNum(8,  "hwnd", AUTORUN_TCHANDLE)
        buf.SetNum(16, "hwnd", 0, _
                       "uint", 0)
        buf.SetNum(32, "ptr", cls.ptr, _                      
                       "dword", 0x00000002)
    Else
        buf.SetNum(0, "dword", buf.size, _   
                      "hwnd", AUTORUN_TCHANDLE, _         
                      "hwnd", 0, _
                      "uint", 0, _
                      "ptr", cls.ptr, _
                      "dword", 0x00000002)
    EndIf    
    DllCall("comdlg32.dll\ChooseColorW", "ptr", buf.ptr, "bool")
    Free(buf, cls)
EndFunc
[/cut]
Вроде всё работает ) Правда, в функции нет обработки результата выбора цвета, но он мне не нужен, так как окно диалога вызывается для других целей.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Хотелось-бы проконсультироваться. Можно-ли прочитать целиком текстовый файл в переменную и поискать в ней нужную информацию?
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):Например, не понятно, нужно ли самому считать размер структуры или где-то есть уже готовые таблицы, типа:
Готовых и простых для использования калькуляторов я не нашел. Как правило такой подсчет основывается на анализе скомпилированного бинарника или при компиляции со специальными отладочными директивами. В любом случае делать это для каждой структуры весьма неудобно.

Для упрощения расчёта смещений написал небольшую утилитку на Autoit, хотел выложить на днях, но раз зашел разговор, можно и сейчас. Все равно дорабатывать я её в ближайшее время вряд ли буду.

Сложную структуру (со вложенными структурами и объединениями) сразу посчитать вряд ли получится. Но что попроще, или если считать вложенные структуры по-отдельности - думаю, справится. С CHOOSECOLORW справляется :)
Orion9 писал(а): поскольку выравнивание (paddiing), если я правильно понимаю, указано неверно
Смещения правильные, размеры вроде тоже.
AkulaBig писал(а):Можно-ли прочитать целиком текстовый файл в переменную и поискать в ней нужную информацию?
В данный момент нет, только через скрипт и ProcessExecGetOutput или через DllCall.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback писал(а):Для упрощения расчёта смещений написал небольшую утилитку на Autoit
Большое спасибо! Посмотрим, что она считает )
Loopback писал(а):Смещения правильные, размеры вроде тоже.
У меня не получилось сделать по той таблице, так что пришлось считать самостоятельно )

Смещения не так страшны, как множество неочевидных типов данных. Хочется больше примеров, чтобы лучше разобраться. Например, никак не могу получить значение из реестра через DllCall:

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

Local key = "Console", val = "FaceName", data, size = 128
res = DllCall("Advapi32.dll\RegGetValueW", "handle", 0x80000001, "wstr", key,  "wstr", val, "dword", 0x00000002, "ptr", 0, "wstr:64", @data, "dword*", @size)
MsgBox("Return: " & res & auCRLF & "Data: " & data & auCRLF & "Size: " & size)
Пробовал разные варианты, много вариантов, но всё время пишет "неправильные параметры". Что здесь не так?

AkulaBig
Чуть ранее был пример с и командой type, не подойдёт?

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

ProcessExecGetOutput out %COMSPEC% '/c type "%file%"'
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):Чуть ранее был пример с и командой type, не подойдёт?
Не, это из другой оперы. У меня тема пока одна, мультиязычность. Хотя сейчас отвлекся. Просто я перешел на скрипт Autorun с заменой названия секций. А мне пишут, что теперь инишники только вручную можно править для внесения своих значений. Так что пришлось опять вернуться на au3.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

AkulaBig
Почему из другой оперы? Вопрос же был:
Можно-ли прочитать целиком текстовый файл в переменную и поискать в ней нужную информацию?
ProcessExecGetOutput out %COMSPEC% '/c type "%file%"' читает целиком текстовый файл в переменную out, в которой затем можно искать информацию.

Loopback
Так и не понял в чём проблема. Сделал то же самое на Autohotkey - работает без проблем:

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

key := "Console", val := "FaceName", size := 128
 data := Buffer(128,0)
 res := DllCall("Advapi32.dll\RegGetValueW", "Ptr", 0x80000001, "Str", key,  "Str", val, "UInt", 0x00000002, "Ptr", 0, "Ptr", data.ptr, "UInt*", &size)
MsgBox("Return: " res . '`n' . "Data: " . StrGet(data, "UTF-16")   . '`n' . "Size: " . size) 
А в Autorun никак:

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

Local key = "Console", val = "FaceName", size = 128
    Local data = Buffer(128)
    data.Zero()
res = DllCall("Advapi32.dll\RegGetValueW", "ptr", 0x80000001, "wstr", key,  "wstr", val, "dword", 0x00000002, "ptr", 0, "ptr", data.ptr, "dword*", @size)
    
    MsgBox("Return: " & res & auCRLF & "Data: " & data.GetStr() & auCRLF & "Size: " & size) 
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):читает целиком текстовый файл в переменную out, в которой затем можно искать информацию.
Искать-то надо средствами Autorun.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

AkulaBig
Ну так в Autorun есть строковые функции :D Та же StrPos.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):Ну так в Autorun есть строковые функции
Я в курсе. Надо будет попробовать еще раз. Может и правда с Type получится.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):Так и не понял в чём проблема. Сделал то же самое на Autohotkey - работает без проблем:
Тут вопрос интерпретации значения первого параметра. Определение HKEY_CURRENT_USER:

((HKEY)(ULONG_PTR)((LONG)0x80000001))

Т.е. в данном случае значение первого параметра должно быть 32-битным беззнаковым целым. Для этого служит тип ulong_ptr, который интерпретирует число как беззнаковое целое с размером указателя. Так всё работает:

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

res = DllCall("Advapi32.dll\RegGetValueW", "ulong_ptr", 0x80000001, "wstr", key,  "wstr", val, "dword", 0x00000002, "ptr", 0, "wstr:64", @data, "dword*", @size)
Но тем не менее, это скорее всего можно назвать багом. Такое число должно работать нормально и с типом handle/ptr.
Ответить