Hide Console Window

Started by MrBcx, July 24, 2024, 02:14:09 PM

Previous topic - Next topic

MrBcx

This is a valid one line of code BCX console mode app:

MSGBOX "Hello, World"

When you compile it as a console app, using your favorite compiler, and then run it,
you will be presented with a Windows MessageBox on top of a black console window.

But what if you don't want to see the console window?  Here's an easy trick ...

1) Wrap your main code into a WINMAIN function, like so ...

FUNCTION WINMAIN

MSGBOX "Hello, World"

FUNCTION = 0
END FUNCTION



2) Now compile it as a GUI app using your favorite compiler


    You get the MSGBOX without the console window.






MrBcx

#1
Here is a more elaborate demonstration that pulls a joke down from
the web (json) and displays it in a MSGBOX, every time this app is run.

These are not my jokes.  Most of the jokes that I read are pretty mild, many
are corny and lame, but some are downright offensive.  You've been warned.

'****************************************************************************
' If you compile this as a GUI, you won't see a console box, only the MSGBOX
'****************************************************************************
FUNCTION WINMAIN
    DIM Url$ AS STRING
    DIM APIData$ * 1024^2
    Url$ = "https://v2.jokeapi.dev/joke/any"
    '***********************************************
    APIData$ = DownloadToStr$ (Url$)
    Sanitize (APIData$)  ' Sanitize json data
    MSGBOX   APIData$    ' Display Joke
    '***********************************************
    RETURN 0
END FUNCTION




FUNCTION DownloadToStr$ (Url$)            ' New updated function by MrBcx - July 24, 2024
    LOCAL Fname$
    Fname$ = TEMPFILENAME$(TEMPDIR$, "any")
    DOWNLOAD (Url$, Fname$)
    DIM Buffer$ * LOF (Fname$) + 1
    IF EXIST (Fname$) THEN
        Buffer$ = LOADFILE$ (Fname$)
        KILL Fname$
        FUNCTION = Buffer$
    ELSE
        FUNCTION = ""
    END IF
END FUNCTION



FUNCTION GetHttpFileSize (url$) AS DWORD   ' New updated function by MrBcx - July 24, 2024
    DIM AS HINTERNET hInternet
    DIM AS HINTERNET hConnect
    DIM AS DWORD fileSize
    DIM AS DWORD bufferSize
    DIM AS DWORD statusCode
    DIM AS DWORD statusSize

    hInternet = InternetOpen ("xcb", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0)
    IF hInternet = NULL THEN
        FUNCTION = 0
    END IF

    hConnect = InternetOpenUrl (hInternet, url$, NULL, 0, INTERNET_FLAG_RELOAD, 0)
    IF hConnect = NULL THEN
        InternetCloseHandle (hInternet)
        FUNCTION = 0
    END IF

    statusSize = SIZEOF(DWORD)    ' Check the HTTP status code
    IF NOT HttpQueryInfo (hConnect, HTTP_QUERY_STATUS_CODE BOR HTTP_QUERY_FLAG_NUMBER, &statusCode, &statusSize, NULL) THEN
        InternetCloseHandle (hConnect)
        InternetCloseHandle (hInternet)
        FUNCTION = 0
    END IF

    IF statusCode <> 200 THEN     ' If the status code is not 200 (OK), treat it as file not found
        InternetCloseHandle (hConnect)
        InternetCloseHandle (hInternet)
        FUNCTION = 0
    END IF

    bufferSize = SIZEOF(DWORD)

    IF NOT HttpQueryInfo (hConnect, HTTP_QUERY_CONTENT_LENGTH BOR HTTP_QUERY_FLAG_NUMBER, &fileSize, &bufferSize, NULL) THEN
        fileSize = 0
    END IF

    InternetCloseHandle (hConnect)
    InternetCloseHandle (hInternet)

    FUNCTION = fileSize
END FUNCTION




SUB Sanitize (A$)
    '**********************************************
    '       Remove unwanted json elements
    '**********************************************
    REMOVE DQ$                       FROM A$
    REMOVE "{"                       FROM A$
    REMOVE "}"                       FROM A$
    IREMOVE "category: Programming," FROM A$
    IREMOVE "category: Spooky"       FROM A$
    IREMOVE "category: Christmas,"   FROM A$
    IREMOVE "category: Misc,"        FROM A$
    IREMOVE "category: Pun,"         FROM A$
    IREMOVE "category: Dark,"        FROM A$
    IREMOVE "delivery:"              FROM A$
    IREMOVE "error: false,"          FROM A$
    IREMOVE "explicit: false"        FROM A$
    IREMOVE "explicit: true"         FROM A$
    IREMOVE "flags:"                 FROM A$
    IREMOVE "lang: en"               FROM A$
    IREMOVE "nsfw: false"            FROM A$
    IREMOVE "nsfw: true"             FROM A$
    IREMOVE "political: false"       FROM A$
    IREMOVE "political: true"        FROM A$
    IREMOVE "racist: false"          FROM A$
    IREMOVE "racist: true"           FROM A$
    IREMOVE "religious: false"       FROM A$
    IREMOVE "religious: true"        FROM A$
    IREMOVE "safe: false"            FROM A$
    IREMOVE "safe: true"             FROM A$
    IREMOVE "setup:"                 FROM A$
    IREMOVE "sexist: false"          FROM A$
    IREMOVE "sexist: true"           FROM A$
    IREMOVE "type: single,"          FROM A$
    IREMOVE "type: twopart,"         FROM A$
    REMOVE ":"                       FROM A$
    REMOVE "  ,"                     FROM A$
    IREMOVE "joke"                   FROM A$
    IREPLACE " s " WITH " jokes "     IN  A$
    REPLACE ".," WITH ("." + CRLF$)   IN  A$
    REPLACE "?," WITH ("?" + CRLF$)   IN  A$
    REPLACE "!," WITH ("!" + CRLF$)   IN  A$
    REPLACE "\n" WITH CRLF$           IN  A$
    REPLACE "\"  WITH CRLF$           IN  A$
    REPEAT 10
        REPLACE "  " WITH SPC$        IN  A$
    END REPEAT
    DIM i
    i = INSTR(A$, " id ")
    IF i THEN A[i] = 0
    A$ = TRIM$(A$)
END SUB





Quin

What happens if you invoke this app from cmd.exe? I'm on a Mac (shutters) so can't test at the second, but from what I recall, the main reason you actually want to compile your binaries in console mode is because they try to create their own console when being initialized as a GUI rather than binding to the calling process (if any).
-Quin.
GitHub

MrBcx

Quote from: Quin on July 24, 2024, 02:58:09 PM
What happens if you invoke this app from cmd.exe?

You get a MSGBOX.

Robert


FUNCTION WINMAIN

? "The eroteme (?) operator, when used in a GUI app, is converted to a MSGBOX statement. "

FUNCTION = 0
END FUNCTION

MrBcx

#5
Quote from: Robert on July 24, 2024, 04:34:05 PM

FUNCTION WINMAIN

? "The eroteme (?) operator, when used in a GUI app, is converted to a MSGBOX statement. "

FUNCTION = 0
END FUNCTION


Yes indeed ... just one of the numerous changes documented in the Revisions.txt
that BCX newcomers especially should be aware of and peek at from time to time.   ;)

See attached screenshot.

**********************************************************************************************
2020/08/05    : Changes in 7.5.2 from 7.5.1
**********************************************************************************************
Kevin Diggins : New: ? operator, when used in a GUI app, is converted to a MSGBOX statement.
                Everything to the right of ? MUST evaluate to a single string expression.
                ?, with nothing else, is allowed and emits a MSGBOX with only an OKAY button.
                Example: ? "Today is " + DATE$ + " and the time is " + TIME$


Robert

This is useful for reporting from apps running in the background.



FUNCTION WINMAIN

DIM YouTalkinToMe$
YouTalkinToMe$ = "This is Security reporting. We have neutralized _
                   a man-in-the middle attack by shoving a worm and a RAT up their yazoo. _
                   Press enter to acknowledge receipt of this message."

DIM oVoice AS OBJECT
COMSET oVoice = CREATEOBJECT("SAPI.SpVoice")
IF BCX_GET_COM_STATUS(&oVoice) THEN oVoice.Speak YouTalkinToMe$
SET oVoice = NOTHING

? YouTalkinToMe$

  FUNCTION = 0
END FUNCTION


Vortex

Inspired by Kliu's hideexec tool, here is an application to run hidden console applications.

The code should be built as a GUI application.


FUNCTION WINMAIN

    DIM procinfo AS PROCESS_INFORMATION
    DIM startinfo AS STARTUPINFO
    DIM ProcResult AS BOOL
    DIM ExitCode AS DWORD
    DIM i AS INTEGER

    ZeroMemory(&startinfo, SIZEOF(startinfo))

    startinfo.cb = SIZEOF(startinfo);
    startinfo.dwFlags = STARTF_USESHOWWINDOW
    startinfo.wShowWindow = SW_HIDE

    ProcResult = CreateProcess(NULL, COMMAND$(1), NULL, NULL, FALSE, _
    CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS , _
    NULL, NULL, &startinfo, &procinfo)

    ExitCode = 0x10000

    ProcResult = (ProcResult<>0)

    FOR i = 0 TO ProcResult
        WaitForSingleObject(procinfo.hProcess, INFINITE)
        GetExitCodeProcess(procinfo.hProcess, &ExitCode);
        CloseHandle(procinfo.hProcess)
        CloseHandle(procinfo.hThread)
    NEXT i

    FUNCTION = ExitCode

END FUNCTION

MrBcx

#8
Quote from: MrBcx on July 24, 2024, 02:27:48 PM
Here is a more elaborate demonstration that pulls a joke down from
the web (json) and displays it in a MSGBOX, every time this app is run.

These are not my jokes.  Most of the jokes that I read are pretty mild, many
are corny and lame, but some are downright offensive.  You've been warned.

Attached to this post is another version of this Joke machine that uses the TinyJson
library that Armando shared with us.  It's easy to use and works great!


'***************************************************
' This version of Joke uses the TinyJson library.
' You must compile this as a 64-bit GUI app.
' It is an easy compile, if you use BED. -- MrBcx
'***************************************************
#include "tinyjson.h"
$PRAGMA comment(lib, "tinyjson.lib")  ' 64-bit lib

FUNCTION WINMAIN
    DIM Url$ AS STRING
    DIM JsonData$
    '***********************************************
    Url$ = "https://v2.jokeapi.dev/joke/any"
    JsonData$ = DownloadToStr$ (Url$)
    '***********************************************
    '            Setup Tiny Json
    '***********************************************
    DIM AS json_t mem [ BCXSTRSIZE ]
    DIM AS CONST json_t PTR json
    json = json_create(JsonData$, mem, UBOUND(mem))
    IF NOT json THEN
        MSGBOX "json_create failed"
        END
    END IF
    '***********************************************
    '             Grab the joke!
    '***********************************************
    DIM a$, b$
    a$ = json_getPropertyValue$(json, "type")
    IF a$ = "single" THEN
        a$ = json_getPropertyValue$(json, "joke")
        MSGBOX a$
    ELSE    'its a "twopart"
        a$ = json_getPropertyValue$(json, "setup")
        b$ = json_getPropertyValue$(json, "delivery")
        MSGBOX a$ + CRLF$ + CRLF$ + b$
    END IF
    '***********************************************
    RETURN 0
END FUNCTION




FUNCTION DownloadToStr$ (Url$)            ' New updated function by MrBcx - July 24, 2024
    LOCAL Fname$
    Fname$ = TEMPFILENAME$(TEMPDIR$, "any")
    DOWNLOAD (Url$, Fname$)
    DIM Buffer$ * LOF (Fname$) + 1
    IF EXIST (Fname$) THEN
        Buffer$ = LOADFILE$ (Fname$)
        KILL Fname$
        FUNCTION = Buffer$
    ELSE
        FUNCTION = ""
    END IF
END FUNCTION





ADDED LATER: 

To filter out most of the super offensive stuff, change the Url$ to:

Url$ = "https://v2.jokeapi.dev/joke/Any?blacklistFlags=racist,sexist,explicit"