Autohotkey: send internal commands with parameters (user defined commands)

English support forum

Moderators: Hacker, petermad, Stefan2, white

Post Reply
Rafaello
Junior Member
Junior Member
Posts: 62
Joined: 2025-04-01, 17:48 UTC

Autohotkey: send internal commands with parameters (user defined commands)

Post by *Rafaello »

TC has a SaveTabs command that only works if it receives parameters. How can I execute it from the outside using Autohotkey? I want to get all the tabs paths from TotalCommander.

Currently I have to create a usercmd.ini first:
Spoiler

Code: Select all

GetTotalCommanderTabs(ByRef winId) {
    ; Creates user command (if necessary) in usercmd.ini 
    ; and uses it to request the current tabs file. 
    ; If the second panel is enabled, file contains tabs from all panels, 
    ; otherwise file contains tabs from the active panel
    
    static TABS_RESULT, CONFIG, COMMAND
    static created := false
    if created
        return TABS_RESULT
    
    ; Search for TC main directory
    static APPDATA_PATH := A_AppData "\GHISLER\"     
    if !FileExist(APPDATA_PATH) {    
        static PATH
        WinGet, PATH, ProcessPath, ahk_id %winId%
        
        ; Remove exe name
        PATH := SubStr(PATH, 1, InStr(PATH, "\",, -12)) 
        APPDATA_PATH := PATH       
    }
        
    TABS_RESULT := APPDATA_PATH "Tabs.tab"
    CONFIG      := APPDATA_PATH "usercmd.ini"
    COMMAND     := "EM_SaveAllTabs"
       
    ; Check and create user command
    loop, 4 {
        ; Read the contents of the config until it appears or the loop ends with an error
        IniRead, _section, % CONFIG, % COMMAND
        if (_section && _section != "ERROR") {
            created := true
            return TABS_RESULT
        }            
        
        ; Set normal attributes (write access)
        FileSetAttrib, n, % APPDATA_PATH
        FileSetAttrib, n, % CONFIG
        sleep, 20 * A_Index
        
        ; Create new section
        FileAppend,
        (LTrim
            # Please dont add commands with the same name
            [%COMMAND%]
            cmd=SaveTabs2 
            param=`"%TABS_RESULT%`"
            
        ), % CONFIG
        sleep, 50 * A_Index
    }
    return LogError(Exception("Unable to create configuration", "Total Commander config", CONFIG " doesnt exist and cannot be created. Create it manually in the " APPDATA_PATH))
}

Then I have to wait for the final file to appear and parse it:
Spoiler

Code: Select all

GetTotalCommanderPaths(ByRef winId) {
    ; Requests a file with current tabs and analyzes it. 
    ; Searches for the active tab using the "activetab" parameter
    global Paths
       
    try { 
        _tabs := GetTotalCommanderTabs(winId)
        try FileDelete, % _tabs
        TotalCommanderUserCommand(winId, "EM_SaveAllTabs")
        
        loop, 600 {
            if FileExist(_tabs) {
                _paths  := []
                
                ; Tabs index starts with 0, array index starts with 1
                _active := _last := 0
                
                Loop, read, % _tabs
                {
                    ; Omit the InStr key and SubStr from value position
                    if (_pos := InStr(A_LoopReadLine, "path=")) {                
                        _paths.push(SubStr(A_LoopReadLine, _pos + 5))
                    }
                    if (_num := InStr(A_LoopReadLine, "activetab=")) {
                        ; Skip next active tab by saving last
                        _active := _last
                        _last   := SubStr(A_LoopReadLine, _num + 10)                
                    }
                }
                
                ; Push the active tab to the global array first
                Paths.push(_paths[_active + 1])
                
                ; Remove duplicate and add the remaining tabs
                _paths.removeAt(_active + 1)
                Paths.push(_paths*)
                return
            }
            sleep, 20
        }
        return LogError(Exception("Unable to access tabs", "Total Commander tabs", "Close Total Commander. The architecture of the script and Total Commander must be the same: " . (A_PtrSize * 8)))
        
    } catch _error {
        LogError(_error)
    }
}
This is very slow and unreliable, as something can go wrong at every step!
Post Reply