Jump to content

How to detect when ConsoleWrite() invisible?


Recommended Posts

CosoleWrite() is handy for debugging.

It is available within SciTE and compiled console .exe's.

How to tell when it is not available / invisible?

I tried testing with

MsgBox(Default,Default,    @CRLF & "Test write to console returned: " & ConsoleWrite( " " ) & "." & @CRLF & @CRLF )

but in all cases, 1 is returned. (I was hoping 0 would be returned when ConsoleWrite()'s can't be seen.)

How to tell when ConsoleWrite() is not available / invisible?

Link to post
Share on other sites
21 minutes ago, Subz said:

You could use @Compiled

I don’t think that is determinative, since to write to the Console an app must be compiled with the /console flag or #pragma.

The help file suggests that ConsoleRead() will set error when not connected to the console, perhaps this can be used, though I have not tested,

Code hard, but don’t hard code...

Link to post
Share on other sites

You can use a substitute to the standard ConsoleWrite to display text to a (or the) console.

It will work the same way uncompiled (run from SciTE via F5), compiled for GUI or compiled to CUI.
The only difference is when you compile for CUI, the standard ConsoleWrite function won't write to the same console. Just don't use it in this case and always use CW() in all cases.

My functions convert and write Unicode (depending on the console default font set). If you wish to use this just set SciTE4AutoIt3 console setting to use Unicode.

#AutoIt3Wrapper_Run_AU3Check=n
#AutoIt3Wrapper_Change2CUI=n


Func CW($s = "")
    (@Compiled ? _CUI_ConsoleWrite : _ConsoleWrite)($s)
EndFunc   ;==>CW


Func _CUI_ConsoleWrite(ByRef $s)
    Local Static $hCon = __CUI_ConsoleInit()
    DllCall("kernel32.dll", "bool", "WriteConsoleW", "handle", $hCon, "wstr", $s & @LF, "dword", StringLen($s) + 1, "dword*", 0, "ptr", 0)
    Return
EndFunc   ;==>_CUI_ConsoleWrite


Func __CUI_ConsoleInit()
    DllCall("kernel32.dll", "bool", "AllocConsole")
    Return DllCall("kernel32.dll", "handle", "GetStdHandle", "int", -11)[0]
EndFunc   ;==>__CUI_ConsoleInit


; Unicode-aware ConsoleWrite
Func _ConsoleWrite($s)
    ConsoleWrite(BinaryToString(StringToBinary($s & @LF, 4), 1))
EndFunc   ;==>_ConsoleWrite


ConsoleWrite("First message"& @LF)
CW("Hello World!" & @LF & "Γειά σου Κόσμε!")
Sleep(2000)

Last note: I set Au3Check to No because it doesn't recognize the ternay construct in CW() and barks at it. The interpreter is immune. You can use a classical If ... Then ... Else ... EndIf instead if you rely on Au3Check.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to post
Share on other sites
31 minutes ago, JockoDundee said:

I don’t think that is determinative, since to write to the Console an app must be compiled with the /console flag or #pragma.

The help file suggests that ConsoleRead() will set error when not connected to the console, perhaps this can be used, though I have not tested,

Nice spot. However, sadly, testing demonstrates it doesn't suit.

$retval = ConsoleRead()
MsgBox(Default,Default, 'ConsoleRead() returned ' & "'" & $retval & "' (" & @error & "," & @extended & ")." & @CRLF )
$retval = ConsoleRead()
ConsoleWrite(           'ConsoleRead() returned ' & "'" & $retval & "' (" & @error & "," & @extended & ")." & @CRLF )

reveals:

ConsoleRead() returned '' (2,0).

then:

ConsoleRead() returned '' (1,0).

If I reverse the MsgBox() and ConsoleWrite() calls, the same results occur. i.e. Error on both calls. Was in SciTE at the time, so the results should have been equal.

Same from a cmd window (except, of course, the ConsoleWrite() calls were not displayed.

From a compiled console app, though, both returned (0,0).

So, nice spot ... but the approach only reveals when in a compiled console .exe - for the in SciTE, and not, use cases, the results are the same, so not getting us to the goal.
 

Link to post
Share on other sites

@bs27975,

Despite my post doesn't answer your initial question, does it solve your problem, provided your actual issue is to be able to reliably write text to a (visible) console in all cases (compiled or not, GUI or CUI)?

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to post
Share on other sites
Posted (edited)
5 hours ago, jchd said:

Despite my post doesn't answer your initial question, does it solve your problem, provided your actual issue is to be able to reliably write text to a (visible) console in all cases (compiled or not, GUI or CUI)?

It seems more complex than it should be. (Not your answer, but that the environment requires such a complex answer.) I have not investigated it.

One would think the obvious correct solution should be ConsoleWrite("") setting a documented @error value that could be tested for that means 'No visible console available.'

> Despite my post doesn't answer your initial question

> does it solve your problem,

This seems chicken and egg - it doesn't answer the question ergo it cannot solve my problem?

> actual issue is to be able to reliably write text to a (visible) console

There is no issue present with this.

> GUI or CUI

GUI was not mentioned and is not in play.

 

The question was only: How to detect when ConsoleWrite() invisible?

or, rephrasing:

How to tell when there is (not) a console present [for ConsoleWrite()]?

 

The answer seems to be - there isn't one.

Ergo:

> One would think the obvious correct solution should be ConsoleWrite("") setting a documented @error value that could be tested for that means 'No visible console available.'

Edited by bs27975
typo corrections.
Link to post
Share on other sites

FYI. ConsoleWrite can be used to communicate between processes in a child/parent mode.  In this particular case, there is no visible console.  And it must not be considered as an error.

Link to post
Share on other sites
2 hours ago, Nine said:

FYI. ConsoleWrite can be used to communicate between processes in a child/parent mode.  In this particular case, there is no visible console.  And it must not be considered as an error.

Nice (spot). Good to know.

Link to post
Share on other sites
On 3/14/2021 at 5:36 PM, bs27975 said:

CosoleWrite() is handy for debugging.

It is available within SciTE and compiled console .exe's.

How to tell when it is not available / invisible?

It is not available/visible when running a compiled Graphical User Interface (GUI) script outside the SCITE editor,   Unless you specify that you want the script compiled as a Console User Interface (CUI) app by using the AutoIt3Wrapper directive "#AutoIt3Wrapper_Change2CUI=Y" or the aut2exe "/console" switch or the pragma "#pragma compile(Console, true)", the script will be compiled as a GUI app.  Keep in mind that when I'm using the term GUI app, I'm not referring to AutoIt GUICreate() and its associated functions, I'm referring to the type of Windows executable.  AutoIt basically creates 2 types of Windows executables, CUI and GUI.  CUI executables are designed to be run within a Windows command console.  The AutoIt ConsoleWrite() function writes to that Windows command console, hence the name ConsoleWrite.  GUI executables run within the Windows graphical environment, not within a Windows command console.  Therefore, using your understanding of ConsoleWrite(), data written using the function is not visible because it is not running in a command console.  Lastly, because of magic happening under the covers, when running a script in SCITE, it can capture the ConsoleWrite() data regardless of whether you have designated the script to be compiled as GUI or CUI.

Assuming that you're using the full Scite4AutoIt editor, you can use the example script below to show the difference when a script is compiled and executed as GUI or CUI.  To do so, just change the Y/N value on the first line, recompile the script (F7), and execute it outside of the editor.

#AutoIt3Wrapper_Change2CUI=N  ;Y = Console App / N = GUI App

#include <Constants.au3>

ConsoleWrite("This was witten to the console." & @CRLF)
MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, "INFO", "IsConsoleWriteVisible() = " & IsConsoleWriteVisible())

Func IsConsoleWriteVisible()
    Const $IMAGE_SUBSYSTEM_WINDOWS_CUI = 0x03

    Local $bReturnValue = False
    Local $hFile = -1
    Local $xImageSubSystem = Binary("")

    ;If running in SCITE
    If Not @Compiled Then
        $bReturnValue = True
    Else
        ;Read the first 0x16D bytes of the executable file.
        ;Byte 0x16D is the Subsystem type in the PE Optional Header.
        ;0x02 = GUI (console write IS NOT visible)
        ;0x03 = CUI (console write IS visible)
        
        $hFile = FileOpen(@AutoItExe, $FO_BINARY)
        If $hFile = -1 Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to open executable file")

        $xImageSubSystem = BinaryMid(FileRead($hFile, 0x16D), 0x16D)

        FileClose($hFile)

        ;If the exe is a CUI app, set flag to True
        If $xImageSubSystem = $IMAGE_SUBSYSTEM_WINDOWS_CUI Then $bReturnValue = True
    EndIf

    Return $bReturnValue
EndFunc

 

Edited by TheXman
Added comments to my example script
Link to post
Share on other sites

Let me try this another way ...

Granted: Compilation as a console app is easily under control, and so detectable. One can set an (internal) variable such as $bRunningAsGUI=False, and then $bConsoleWriteVisible=(@compiled and $bRunningAsGUI = False)

So the question becomes / is actually:

How to tell when being run from SciTE?

Link to post
Share on other sites
> My example takes care of all the scenarios, including IF YOU ARE RUNNING IN SCITE OR NOT!

Not what I asked.

>> How to tell when being run from SciTE?

IDGAF whether it was what you asked or not! :ranting:  If you took the time to understand the script and read the help file, you would see that your question was answered in my example script.  I'm out!

Edited by TheXman
Link to post
Share on other sites
7 hours ago, bs27975 said:

The answer seems to be - there isn't one.

Eureka!  I thought you were wrong at first, but you’ve seen further...there is just no answer to this stupendous stumper,  

Good Catch (Spot)!

We were all baffled, how could we have not come across this before.  Unbelievable!

Thanks again!

Because of you I now know what to do when I need to make sure that visible characters are showing up or not on the screen regardless of if I am running compiled, uncompiled or from the IDE - I should just Give Up!

 

Code hard, but don’t hard code...

Link to post
Share on other sites

I should just Give Up!

😂

Well ... no - just depends upon how complex an answer / solution you can tolerate. Complex and overly complicate (due to the environment) answers are present.

Perhaps a documented @error value upon ConsoleWrite("") could be created to mean "No visible console present." Or something.

What is also clear is how poorly I phrased the initial question, making assumptions I didn't know I was making. e.g. Not contemplating a GUI compiled environment at the time, nor considering that there is always a Console present to write to - it just can't be seen. (ergo, ConsoleWrite() unavailable was poor phrasing.)

- and it is easy to lose sight of the significant depth of AutoIt (making such complex answers even possible in the first place).

When I figure out the desired solution, I will edit the OP so that those going TL;DR don't have to dig into the excellent points made, if they aren't interested.

For the moment, the outstanding bit is detecting that we are running from within SciTE or not. I'm guessing '@AutoItExe contains scite and exe', or @ScriptName, isn't useful for this, but I haven't gotten as far as doing any tests yet.

Link to post
Share on other sites
1 hour ago, argumentum said:

aggravated by the OP user

You shouldn't be.

I saw your post, appreciated it, and captured the details.

I just haven't had a chance chew it over yet.

-----

Moreover ...

It seems that we were both composing at the same time.

"I should just Give Up!" was an appreciative response to the post prior to yours.

Not to your much appreciated post of good stuff (that I haven't had a chance to chew over, yet).

Yours just got in before mine.

So don't take "I should just Give Up!" as a response to yours - it wasn't.

- please re-post yours, it was entirely topical and an appreciated contribution to this thread.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...