Running a Julia Programm without a Window popping up

Is it possible to start a Julia program via a shortcut so that no window opens? I’ve been struggling with this for days and can’t find an easy solution.

I just wrote the following micro program to test it:

File: test.jl
sleep(120)

Then I created a shortcut on the Windows desktop. with the content:

...julia.exe test.jl

When I call the shortcut a window always pops up.

Who can present me a good advice or a solution to prevent this?

Ralf

1 Like

This VBScript solution is easy and works well:
Create a file e.g. test.vbs with the following content:

Dim WShell
Set WShell = CreateObject("WScript.Shell")
WShell.Run "julia -t 4 d:\Temp\crtest.jl", 0
Set WShell = Nothing

The
julia -t 4 d:\Temp\crtest.jl
is what I used to test it, change it to your call to julia.
I found this here: Run a program hidden in Windows 10 with other alternative methods.

2 Likes

Thank you for your contribution. I had of course hoped that a solution with Julia’s own tools would be possible, but as long as these are not available for Julia I am happy to have a working backup.

I believe this is not Julia’s problem (EDIT: it is on Windows), so the upside is that you could look into how others handle this, e.g. Python, and the solution should translate. I sort of have a solution below.

This is a surprisingly deep and interesting problem so I looked into it.

EDIT: Intriguingly, I see this is solved in Python (since Python 3.3) with just changing the file extension to .pyw (but that works only in Windows I think, i.e. a separate extension is only needed there):

I’m not proposing similar .jlw extension yet (since I like just one consistent standard), but it seems it might be the only solution(?), i.e. in Windows (unlike Linux/Unix) the extension controls what program is run, and I think Python wouldn’t have solved it this way unless they REALLY rather needed to rather run with pythonw.exe (which is not needed except on Windows, what I was looking into and assumed was based on my Linux knowledge) instead of regular python.exe, which is a different (console) type of application. You could always use Python as your main (top) language and call Julia from it… with pycall. It’s trivial to do in the other direction, and embed python code in your julia code, with the py macro, but Python doesn’t have macros, so I’m not sure and haven’t looked much yet if you could do similar (i.e. in one program file). For now you could also just use Python, and it’s sometimes better for (short-running) scripts. What I wrote below, assumed it’s not the programs responsibility to open the terminal (likely right for Linux/scripts), but it is on Windows, why a different non-console .exe is used. It seems at best, for now, Julia must open that unless it’s invoked from a different program that already didn’t open a window:

When your (Julia) program runs IN the terminal you have “standard” input and output, no windowing/GUI support, only what the terminal (Windows) support. To get anything MORE, i.e. a “GUI” window, is non-portable, and a bit surprisingly getting anything less (no window) might also be, but I’m not sure so I’ll explain the problem:

If you had no window, and your program prints to the (standard) output, where would you want the output to go? [The same problem exists with “standard error” (e.g. if your program throws an exception).]

It IS a good user-interface to provide a window/terminal, for the possible output, I realize you expect none, but if it’s a possibility then opening right away, not waiting until it happens, is better, because the user should have some indication the program started, an empty window (or it printing “Program started, please wait for it to finish, or the possible output…”).

If the program is a batch program, a “service” in Windows language, that should of course be possible (certainly is in Linux), but then it wouldn’t be started manually, certainly not from an icon.

I could do this, sort of, in my second program, but first what I tried to be cross-platform:

#!/home/pharaldsson/.julia/juliaup/bin/julia
"""
println("Hello world!")
""" |>
run(`/home/pharaldsson/.julia/juliaup/bin/julia -`; wait=false)
# run(`/home/pharaldsson/.julia/juliaup/bin/julia -e "sleep(1);"`; wait=false)
#sleep(1)

That method works if for the run you can point to a different Julia program file, or if you Julia program fits into a one-liner, as I did in the second, commented out line with -e option. But I wanted to explore what I could do in just one file, so this is in some way better:

#!/bin/bash

cat << EOF | /home/pharaldsson/.julia/juliaup/bin/julia - & disown
# My Julia program
sleep(1)
println("Hello world!")
# End of my Julia program
EOF

As you can see I’m using bash shell, which you can rely on in Linux, but not on macOS, and changing this to /bin/sh, makes it portable to macOS, but then the bash builtin disown no longer works…

The command disown is key to this (or wait=false in the other program), and I can thank you for learning of its existence.

Since bash IS included in modern Windows this actually works in Windows, i.e. or should work in WSL[2], I just can’t check since I don’t have windows, nor do I know of icon/shortcut support with WSL.

It’s not Julia that opens the terminal (in Linux, at least), it’s opened for any script, and the trick is you want it closed, e.g. with disown, to detach from that terminal:

4. Using nohup

[…]

5. Using disown

We can run a command and have the terminal disown the process by appending “& disown at the end: […]

6. Using setsid

When we run a command with setsid, the command starts in a new session that is disconnected from the current terminal.

As you can see, there are several ways, at least in Linux/Unix, and I tried to reverse-engineer what disown does, with:

$ strace ./test_win.jl & disown

I’m not sure that way is effective to do that, but knowing what disown does is likely the key to knowing the best way.

You CAN actually compile Julia programs to binary executables with e.g. PackageCompiler.jl, and I thought that might be one solution, but I think it will not automatically solve the problem, and even makes your program less portable… You could also look into GTK.jl or QML.jl which CAN open a GUI windows, and just choose to open none.

1 Like

For Windows, someon me would need to compile the Julia executable like this:

1 Like

A juliac.exe (or better name) would be quite nice. The c=console is clearly bad naming in this case, it is inspired from other programs where name has a GUI and namec not.

juliac is the name a static compiler that got merged into PackageCompiler.jl:

1 Like

The convention is just to add w. For example, javaw.

Or pythonw:

1 Like

juliaw.exe it shall be :wink:

It’s seems like you confirmed, you need to recompile the Julia executable, i.e. julia.exe, the main one (not someones, Julia-compiled to app, though that would be another option), and otherwise you’ve get a console windows (at least briefly blinking, in case you can get it to close; doesn’t seem impossible with a hack).

@Ralf_Dietrich since I don’t have Windows to test on, can anyone check my solution/workaround, i.e. not the one with any recompilation, in Windows (and/or in WSL)?

Looking into the Windows-specific thing, I see you need to invoke the (compiler(or actually since the option is passed to the) linker with “windows”:

–subsystem which : major . minor
Specifies the subsystem under which your program will execute. The legal values for which are “native”, “windows”, “console”, “posix”, and “xbox”.

Seeing this, it got me curious could you support “xbox” that way (i.e. Xbox One)? Of course you wouldn’t want a console windows popping up there either, and likely the default (“console”; nor “windows”) of Julia would work there. The CPU of the Xbox One shouldn’t be a hindrance, and the OS is basically Windows, with some limitations, but it’s similar enough that this trivial change might work, or possibly even no change needed? I believe there’s also an issue of actually getting your software to the actual console…, not sure.