[v2] FileAppend to stdout not working

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
ahkpadawan
Posts: 5
Joined: 02 Mar 2023, 13:44

[v2] FileAppend to stdout not working

Post by ahkpadawan » 02 Mar 2023, 13:53

Hello everybody,

I'm trying to do some printing to stdout from my function but it causes syntax errors when doubleclicking the .ahk file.
I'm kinda lost, running out of ideas. It's AHK 2.0.2. Pasting the relevant part of the script below. Please help.
image.png
image.png (75.85 KiB) Viewed 973 times


[Mod action: Topic moved from "Bug Reports", which is for reporting bugs in AHK, not for help in debugging your scripts.]

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: [v2] FileAppend to stdout not working

Post by teadrinker » 02 Mar 2023, 15:05

* is a string, so quotes must be used.
ahkpadawan wrote: It's AHK 2.0.2
In AHK v2 there is no Clipboard variable, it was replaced by A_Clipboard.

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: [v2] FileAppend to stdout not working

Post by boiler » 02 Mar 2023, 17:23

...and even so, if you change the line Cliboard := "%Clipboard% to A_Clipboard := "%A_Clipboard%", you will just have placed the actual text %A_Clipboard% in the clipboard.

ahkpadawan
Posts: 5
Joined: 02 Mar 2023, 13:44

Re: [v2] FileAppend to stdout not working

Post by ahkpadawan » 13 Mar 2023, 06:35

teadrinker wrote:
02 Mar 2023, 15:05
* is a string, so quotes must be used.
It then yields "Error: (6) The handle is invalid."...

Image

%A_Clipboard%

teadrinker wrote:
02 Mar 2023, 15:05
ahkpadawan wrote: It's AHK 2.0.2
In AHK v2 there is no Clipboard variable, it was replaced by A_Clipboard.

[Mod edit: Fixed quote tags where replies including OP’s reply were attributed to the wrong posters.]

ahkpadawan
Posts: 5
Joined: 02 Mar 2023, 13:44

Re: [v2] FileAppend to stdout not working

Post by ahkpadawan » 13 Mar 2023, 08:16

boiler wrote:
02 Mar 2023, 17:23
...and even so, if you change the line Cliboard := "%Clipboard% to A_Clipboard := "%A_Clipboard%", you will just have placed the actual text %A_Clipboard% in the clipboard.
Yes, thanks for pointing that out. I found the solution in docs:

This is how to save the contents of the clipboard in v2: https://www.autohotkey.com/docs/v2/lib/ClipboardAll.htm#ExVar
This is how to convert contents of the clipboard to plain text in v2: https://www.autohotkey.com/docs/v2/lib/A_Clipboard.htm#ExPlain

So the working script now looks like:

Code: Select all

^+v::   ; paste clipboard contents as plain text
{
  ClipboardOld := ClipboardAll()   ;save original clipboard contents
  A_Clipboard := A_Clipboard       ;store plain text from clipboard to clipboard
  Send "^v"       ;send the Ctrl+V command
  Sleep 250       ;give some time to finish paste (before restoring clipboard)
  A_Clipboard := ClipboardOld      ;restore the original clipboard contents
  ClipboardOld := ""               ;clear temporary variable (potentially contains large data)
}
The FileAppend still doesn't work, though.
I think there should be much simpler way to print text to stdout.

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: [v2] FileAppend to stdout not working

Post by swagfag » 16 Mar 2023, 10:29

to print text to stdout, u need to have a stdout to print text to
which is something that according to the error message, at least, u dont have...

https://learn.microsoft.com/en-us/windows/console/allocconsole
https://learn.microsoft.com/en-us/windows/console/attachconsole

this is as simple as it gets

User avatar
Mono919
Posts: 71
Joined: 05 May 2022, 02:36

Re: [v2] FileAppend to stdout not working

Post by Mono919 » 16 Mar 2023, 11:16

swagfag wrote:
16 Mar 2023, 10:29
to print text to stdout, u need to have a stdout to print text to
which is something that according to the error message, at least, u dont have...

https://learn.microsoft.com/en-us/windows/console/allocconsole
https://learn.microsoft.com/en-us/windows/console/attachconsole

this is as simple as it gets
this is the example of using stdout with console.

Code: Select all

class console
{
    static AllocConsole()
    {
        return dllcall("AllocConsole")
    }
    
    static AttachConsole(dwProcessId)
    {
        return dllcall("AttachConsole", "uint", dwProcessId)
    }
    
    static FreeConsole()
    {
        return dllcall("FreeConsole")
    }
}

class stdio
{
    static stdin
    {
        get
        {
            static ret := dllcall(cextra.funcAddress("__iob_func"), "uptr")
            return ret
        }
    }
    static stdout
    {
        get
        {
            static ret := this.stdin + a_ptrsize
            return ret
        }
    }
    static stderr
    {
        get
        {
            static ret := this.stdin + 2 * a_ptrsize
            return ret
        }
    }
    
    static fclose(__stream)
    {
        static funcAddr := cextra.funcAddress("fclose")
        return dllcall(funcAddr, "ptr", __stream)
    }
    
    static fflush(__stream)
    {
        static funcAddr := cextra.funcAddress("fflush")
        return dllcall(funcAddr, "ptr", __stream)
    }
    
    static fopen(__filename, __mode)
    {
        static funcAddr := cextra.funcAddress("fopen")
        if (__filename is string)
            __filename := cextra.strBuffer(__filename)
        if (__mode is string)
            __mode := cextra.strBuffer(__mode)
        return dllcall(funcAddr, "ptr", __filename, "ptr", __mode, "uptr")
    }
    
    static freopen(__filename, __mode, __stream)
    {
        static funcAddr := cextra.funcAddress("freopen")
        if (__filename is string)
            __filename := cextra.strBuffer(__filename)
        if (__mode is string)
            __mode := cextra.strBuffer(__mode)
        return dllcall(funcAddr, "ptr", __filename, "ptr", __mode, "ptr", __stream, "uptr")
    }
    
    static fprintf(__stream, __format, args*)
    {
        static funcAddr := cextra.funcAddress("fprintf")
        if (__format is string)
            __format := cextra.strBuffer(__format)
        dllbind := dllcall.bind(funcAddr, "ptr", __stream, "ptr", __format)
        for i in args
        {
            if (i is string)
                i := cextra.strBuffer(i)
            if (i is array)
                dllbind := dllbind.bind(i*)
            else
                dllbind := dllbind.bind("ptr", i)
        }
        return dllbind()
    }
    
    static fscanf(__stream, __format, args*)
    {
        static funcAddr := cextra.funcAddress("fscanf")
        if (__format is string)
            __format := cextra.strBuffer(__format)
        dllbind := dllcall.bind(funcAddr, "ptr", __stream, "ptr", __format)
        for i in args
        {
            if (i is array)
                dllbind := dllbind.bind(i*)
            else if (i is buffer)
                dllbind := dllbind.bind("ptr", i)
            else
                dllbind := dllbind.bind("ptr*", i)
        }
        return dllbind()
    }
    
    static getchar()
    {
        static funcAddr := cextra.funcAddress("getchar")
        return chr(dllcall(funcAddr))
    }
    
    static printf(__format, args*)
    {
        stdio.freopen("conout$", "w", stdio.stdout)
        return (ret := stdio.fprintf(stdio.stdout, __format, args*), stdio.fclose(stdio.stdout), ret)
    }
    
    static putchar(__character)
    {
        static funcAddr := cextra.funcAddress("putchar")
        if __character is string
            __character := ord(__character)
        return dllcall(funcAddr, "int", __character)
    }
    
    static scanf(__format, args*)
    {
        stdio.freopen("conin$", "r", stdio.stdin)
        return (ret := stdio.fscanf(stdio.stdin, __format, args*), stdio.fclose(stdio.stdin), ret)
    }
}

class cextra
{
    static core_module := dllcall("LoadLibrary", "str", "msvcrt.dll", "uptr")
    
    static bufString(buf)
    {
        str := ""
        while (a_index <= buf.size) && (current := numget(buf, a_index - 1, "char"))
            str .= chr(current)
        return str
    }
    
    static strBuffer(str, encoding := "utf-8")
    {
        buf := buffer(strput(str, encoding))
        strput(str, buf, encoding)
        return buf
    }
    
    static funcAddress(funcname)
    {
        return dllcall("GetProcAddress", "ptr", this.core_module, "ptr", this.strBuffer(funcname), "uptr")
    }
}

class malloc
{
    static calloc(__count, __size)
    {
        static funcAddr := cextra.funcAddress("calloc")
        return dllcall(funcAddr, "uint", __count, "uint", __size)
    }
    
    static free(__block)
    {
        static funcAddr := cextra.funcAddress("free")
        return dllcall(funcAddr, "ptr", __block)
    }
    
    static malloc(__size)
    {
        static funcAddr := cextra.funcAddress("malloc")
        return dllcall(funcAddr, "uint", __size)
    }
    
    static realloc(__block, __size)
    {
        static funcAddr := cextra.funcAddress("realloc")
        return dllcall(funcAddr, "ptr", __block, "uint", __size)
    }
}

class stdlib
{
    static abort()
    {
        static funcAddr := cextra.funcAddress("abort")
        return dllcall(funcAddr)
    }
    
    static bsearch(__key, __base, __numofelements, __sizeofelements, __comparefunction)
    {
        static funcAddr := cextra.funcAddress("bsearch")
        if __comparefunction is func
            __comparefunction := callbackcreate(__comparefunction, "cdel")
        return (ret := dllcall(funcAddr, "ptr", __key, "ptr", __base, "uint", __numofelements, "uint", __sizeofelements, "int", __comparefunction), callbackfree(__comparefunction), ret)
    }
    
    static exit(code)
    {
        static funcAddr := cextra.funcAddress("exit")
        return dllcall(funcAddr, "int", code)
    }
    
    static itoa(__value, __radix)
    {
        static funcAddr := cextra.funcAddress("_itoa_s")
        buf := buffer(1024)
        dllcall(funcAddr, "int", __value, "ptr", buf, "uint", buf.size, "int", __radix)
        return strget(buf, , "utf-8")
    }
    
    static qsort(__base, __numofelements, __sizeofelements, __comparefunction)
    {
        static funcAddr := cextra.funcAddress("qsort")
        if __comparefunction is func
            __comparefunction := callbackcreate(__comparefunction, "cdel")
        return (ret := dllcall(funcAddr, "ptr", __base, "uint", __numofelements, "uint", __sizeofelements, "int", __comparefunction), callbackfree(__comparefunction), ret)
    }
    
    static rand()
    {
        static funcAddr := cextra.funcAddress("rand")
        return dllcall(funcAddr)
    }
    
    static srand(__seed)
    {
        static funcAddr := cextra.funcAddress("srand")
        return dllcall(funcAddr, "int", __seed)
    }
    
    static strtol(__string, __radix, &__endptr := 0)
    {
        static funcAddr := cextra.funcAddress("strtol")
        if (__string is string)
            __string := cextra.strBuffer(__string)
        return dllcall(funcAddr, "ptr", __string, "ptr*", &__endptr, "int", __radix)
    }
    
    static strtoul(__string, __radix, &__endptr := 0)
    {
        static funcAddr := cextra.funcAddress("strtoul")
        if (__string is string)
            __string := cextra.strBuffer(__string)
        return dllcall(funcAddr, "ptr", __string, "ptr*", &__endptr, "int", __radix)
    }
    
    static system(__command)
    {
        static funcAddr := cextra.funcAddress("system")
        if (__command is string)
            __command := cextra.strBuffer(__command)
        return dllcall(funcAddr, "ptr", __command)
    }
}

console.AllocConsole()
stdio.printf("123`n")
stdlib.system("pause")

ahkpadawan
Posts: 5
Joined: 02 Mar 2023, 13:44

Re: [v2] FileAppend to stdout not working

Post by ahkpadawan » 17 Mar 2023, 12:58

swagfag wrote:
16 Mar 2023, 10:29
to print text to stdout, u need to have a stdout to print text to
which is something that according to the error message, at least, u dont have...

https://learn.microsoft.com/en-us/windows/console/allocconsole
https://learn.microsoft.com/en-us/windows/console/attachconsole

this is as simple as it gets
I would expect AHK to output stdout to its main window, where it prints tons of meaningless stuff :)

Image

ahkpadawan
Posts: 5
Joined: 02 Mar 2023, 13:44

Re: [v2] FileAppend to stdout not working

Post by ahkpadawan » 17 Mar 2023, 13:01

Mono919 wrote:
16 Mar 2023, 11:16
this is the example of using stdout with console.
OMG thank you but no :) It would probably be shorter in assembler :)
I thought about something as simple as "print" statement or function, outputting stuff to the console in which AHK is run, and in case there's no console, to the main window. Or both, why not.

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: [v2] FileAppend to stdout not working

Post by swagfag » 17 Mar 2023, 15:08

ahkpadawan wrote:
17 Mar 2023, 12:58
I would expect AHK to output stdout to its main window, where it prints tons of meaningless stuff :)
i dont know why ud have an expectation of the sorts. the script's window is not a console nor does it particularly resemble one. the docs dont say anywhere ud be able to do such a thing either.

that said, u could write stuff to that window. i wouldnt recommend it, since ahk uses the window to print its own stuff on it, but u could do it nevertheless

Code: Select all

#Requires AutoHotkey v2.0.2

AppendToScriptWindow(newText) {
	oldText := ControlGetText('Edit1', A_ScriptHwnd)
	ControlSetText(oldText '`r`n' newText, 'Edit1', A_ScriptHwnd)
}

Post Reply

Return to “Ask for Help (v2)”