Hello! I am working on something where I am trying to pass data between .NET, namely F#, and Elixir through the command line. On Windows, I am getting a strange error that I can’t figure out.
Here is my F# function:
let executeProcess name arguments =
let startInfo = System.Diagnostics.ProcessStartInfo(
FileName = name,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
)
use p = new System.Diagnostics.Process(StartInfo = startInfo)
p.Start() |> printfn "Successfull?: %A"
p.WaitForExit()
p.StandardOutput.ReadToEnd()
On Ubuntu, this works without issue (you can try by copy and pasting this into a dotnet fsi
session after downloading the latest .NET SDK or you can try it in a Polyglot Notebook in VS Code, which requires no install I believe as it installs F# for you):
$ dotnet fsi
Microsoft (R) F# Interactive version 12.4.0.0 for F# 7.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> <copy and paste above function>;;
val executeProcess: name: string -> arguments: string -> string
> executeProcess "dotnet" "--version";;
Successfull?: true
val it: string = "7.0.101
"
> executeProcess "elixir" "--version";;
Successfull?: true
val it: string =
"Erlang/OTP 25 [erts-13.1.4] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]
Elixir 1.14.3 (compiled with Erlang/OTP 25)
"
>
However, on Windows, I get a strange Erlang init error but notice that Elixir works just fine on the command line:
PS > elixir.bat --version
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]
Elixir 1.14.2 (compiled with Erlang/OTP 25)
PS > dotnet fsi
Microsoft (R) F# Interactive version 12.8.0.0 for F# 8.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> <copy and paste above command>;;
val executeProcess: name: string -> arguments: string -> string
> executeProcess "dotnet" "--version";;
Successfull?: true
val it: string = "8.0.100-preview.6.23330.14
"
> executeProcess "elixir.bat" "--version";;
Successfull?: true
val it: string =
"{"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_em,1,[{file,"init.erl"},{line,1220}]},{init,do_boot,3,[{file,"init.erl"},{line,910}]}]}}
"
This is where I get this weird error of {"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_em,1,[{file,"init.erl"},{line,1220}]},{init,do_boot,3,[{file,"init.erl"},{line,910}]}]}}
. Searching and even looking up the line numbers in init.erl
, this error seems to be because of Erlang version issues. However, that is not an issue on my machine. Elixir and Erlang via iex
and erl
work just fine, as does elixir.bat --version
from the command line.
There seems to be something in how the .NET process launcher is interacting with the Elixir.bat that one or the other doesn’t like. Does anyone know what’s going on here? Is this an issue with elixir.bat
on Windows?
(Note: There is a workaround, and it is to actually make the filename "powershell"
with arguments "elixir --version"
. However, I don’t know why that works and the other doesn’t. The Elixir binaries/scripts are in my path, as are the Erlang binaries.)
Edit: I went ahead and tried this on the latest versions of Elixir 1.15.4 and Erlang/OTP 26. The Erlang "init terminated in do_boot"
error seems to have gone away, but nothing is written to standard out when running this code as above. However, if I remove the redirection from standard out and reading, I get the following error in FSI:
> let executeProcess name arguments =
- let startInfo = System.Diagnostics.ProcessStartInfo(
- FileName = name,
- Arguments = arguments
- )
- use p = new System.Diagnostics.Process(StartInfo = startInfo)
- p.Start() |> printfn "Successfull?: %A"
- ;;
val executeProcess: name: string -> arguments: string -> unit
> executeProcess "elixir.bat" "--version";;
Successfull?: true
val it: unit = ()
> Error! Failed to load module 'elixir' because it cannot be found. Make sure that the module name is correct and
that its .beam file is in the code path.
Runtime terminating during boot ({undef,[{init,start_it,1,[{_},{_}]},{init,start_em,1,[{_},{_}]},{init,do_boot,3,[{_},{_}]}]})
Crash dump is being written to: erl_crash.dump...done