leafac/caxa

Hide console window

Closed this issue · 11 comments

Is there any possible way to hide the console of an application compiled with caxa ,either a third party package or a feature built into caxa.

I guess it depends on the operating system and on the way you open the application (for example, from the command-line vs double-clicking on the file in a file explorer). Can you give us more information?

My main goal was to run the application just by double-clicking it and without it showing a terminal window, pretty similar to the way pyinstaller works when you specify the --windowed flag.

I've found a workaround for this on Windows.

  1. Copy your node.exe to the same location as your package.json
  2. If you are using the command line, make a new script file and use the caxa api function with instructions to generate a build (like the one example in caxa's readme.md)
  3. Use a tool like PE-Bear to open up the node.exe that you just copied into your folder, go to the optional headers and change the subsystem from 3 to 2 (from console to Windows GUI) and save the executable by overwriting it (find the option called "Save executable as...")
  4. go to your package.json and add a new script but instead of calling your nodejs installed globally, tell it to use the node.exe from your folder (eg. "build": "node.exe build.js")
  5. Once the process is finished, take the executable that was generated and do the same process with PE-Bear

Okay so I actually managed to automate this using python 3.10 and a package called lief
here's an example (don't modify the build script in package.json tho)

import subprocess
import shutil
import os
import os.path
import lief

node_executable = os.getcwd()+"\\node.exe"
if (os.path.exists(node_executable)):
    os.remove(node_executable)

shutil.copyfile("C:\\Program Files\\nodejs\\node.exe", node_executable)

binary = lief.parse(node_executable)
#binary.optional_header.subsystem = lief.PE.SUBSYSTEM.WINDOWS_CUI
binary.optional_header.subsystem = lief.PE.SUBSYSTEM.WINDOWS_GUI
binary.write('node.exe')

o = subprocess.Popen(['cmd', '/c', r'npm run build'])
o.wait()

generated_executable = os.getcwd()+"\\teste.exe"
binary = lief.parse(generated_executable)
#binary.optional_header.subsystem = lief.PE.SUBSYSTEM.WINDOWS_CUI
binary.optional_header.subsystem = lief.PE.SUBSYSTEM.WINDOWS_GUI
binary.write('teste.exe')

Here's an example using node-raylib

Thanks for the example and everything 👏

One more question about how this would work:

When you start the application and a window does not open for it, how should users see the outputs, and how would they stop the application?

Perhaps this is meant for graphical applications that will open their own windows and manage their own lifecycle?

Thanks for the example and everything 👏

One more question about how this would work:

When you start the application and a window does not open for it, how should users see the outputs, and how would they stop the application?

Theoretically the only way to stop it is from task manager in windows for example, but it depends on what sort of app you are building.

Perhaps this is meant for graphical applications that will open their own windows and manage their own lifecycle?

With that being said, yep, that's exactly what this is intended for! Graphical apps (like this one repo that I posted in this example) This project uses node-raylib, in which is sort of like SDL2 a graphical module, in this case the application stops as soon as the window is closed, although for obvious reasons I can't recommend using this method of hiding the console if you are building a server for example as there is no clear way of stopping it (maybe with a little tray icon?)

@joao678 Sounds good. Thanks for the answers. I’ll look into creating an option for this in the next version of caxa.

I think I have a related issue. On Windows running a binary of a node app created with caxa opens the console window by default. When the packaged app finishes, the console window closes by default. There are many situations where you would like the console window to remain open after the app finishes.
You may have have output to the console that you wrote and that you want to review when the app finishes. Or if there is an error in the input file that causes an error in the node app (e.g., file is not found, or there is a misplaced comma in a json file), you'd like to see the error message to fix the problem. It seems that you have to go back to the unpackaged app and run it under node to see any output or error messages when the app terminates. This takes a lot away from the advantage of packaging the app with caxa. So is there a way for the console window to stay open after a packaged app closes (either normal termination or from an error)?

@sjscotti your issue is probably trivially resolved by adding an infinite sleep to your app where you would otherwise exit.

Hi y’all,

Thanks for using caxa and for the conversation here.

I’ve been thinking about the broad strategy employed by caxa and concluded that there is a better way to solve the problem. I think it may make this use-case more straightforward to implement, as it works with a Windows Batch file, not an executable.

It’s a different enough approach that I think it deserves a new name, and it’s part of a bigger toolset that I’m building, which I call Radically Straightforward · Package.

I’m deprecating caxa and archiving this repository. I invite you to continue the conversation in Radically Straightforward’s issues.

Best.