public override CmdAhornGetInfo.Info Run(string rootPath, string vhdPath, string vhdMountPath, string mode)
        {
            // Make sure that the default Olympus Ahorn root folder exists.
            AhornHelper.Mode     = AhornHelperMode.System;
            AhornHelper.RootPath = null;
            if (!Directory.Exists(AhornHelper.RootPath))
            {
                Directory.CreateDirectory(AhornHelper.RootPath);
            }

            AhornHelper.RootPath     = string.IsNullOrEmpty(rootPath) ? rootPath : Path.GetFullPath(rootPath);
            AhornHelper.VHDPath      = string.IsNullOrEmpty(vhdPath) ? vhdPath : Path.GetFullPath(vhdPath);
            AhornHelper.VHDMountPath = string.IsNullOrEmpty(vhdMountPath) ? vhdMountPath : Path.GetFullPath(vhdMountPath);
            if (!Enum.TryParse(mode, true, out AhornHelper.Mode))
            {
                AhornHelper.Mode = AhornHelperMode.System;
            }

            AhornHelper.FindJulia(false);
            AhornHelper.FindAhorn(false);
            if (!Directory.Exists(AhornHelper.RootPath))
            {
                Directory.CreateDirectory(AhornHelper.RootPath);
            }

            return(new CmdAhornGetInfo.Info());
        }
Exemple #2
0
        public override IEnumerator Run(string script, bool?localDepot)
        {
            string tmpFilename = null;

            try {
                using (ManualResetEvent timeout = new ManualResetEvent(false))
                    using (Process process = AhornHelper.NewJulia(out tmpFilename, script, localDepot)) {
                        process.Start();

                        bool         dead            = false;
                        bool         deadByTimeout   = false;
                        int          timeoutThreadID = 0;
                        int          lineID          = 0;
                        WaitHandle[] timeoutHandle   = new WaitHandle[] { timeout };
                        Thread       killer          = null;

                        for (string line; (line = process.StandardOutput.ReadLine()) != null;)
                        {
                            if (line.StartsWith("#OLYMPUS# "))
                            {
                                line = line.Substring("#OLYMPUS# ".Length);
                                if (line == "TIMEOUT START")
                                {
                                    if (killer == null)
                                    {
                                        timeoutThreadID++;
                                        timeout.Reset();
                                        killer = new Thread(() => {
                                            int timeoutThreadIDCurrent = timeoutThreadID;
                                            int lineIDCurrent          = lineID;
                                            try {
                                                while (!dead && timeoutThreadID == timeoutThreadIDCurrent)
                                                {
                                                    int waited = WaitHandle.WaitAny(timeoutHandle, 15 * 60 * 1000);
                                                    timeout.Reset();
                                                    if (waited == WaitHandle.WaitTimeout && !dead && timeoutThreadID == timeoutThreadIDCurrent && lineID == lineIDCurrent)
                                                    {
                                                        dead          = true;
                                                        deadByTimeout = true;
                                                        process.Kill();
                                                        return;
                                                    }
                                                    lineIDCurrent = lineID;
                                                }
                                            } catch {
                                            }
                                        })
                                        {
                                            Name         = $"Olympus Julia watchdog thread {process}",
                                            IsBackground = true
                                        };
                                        killer.Start();
                                    }
                                }
                                else if (line == "TIMEOUT END")
                                {
                                    timeoutThreadID++;
                                    killer = null;
                                    timeout.Set();
                                }
                                else
                                {
                                    process.Kill();
                                    throw new Exception("Unexpected #OLYMPUS# command:" + line);
                                }
                            }
                            else
                            {
                                lineID++;
                                timeout.Set();
                                line = Escape(line, out bool update);
                                if (line != null)
                                {
                                    yield return(Status(DateTime.Now.ToString("[HH:mm:ss] ") + line, false, "", update));
                                }
                            }
                        }

                        process.WaitForExit();
                        dead = true;
                        timeout.Set();
                        killer?.Join();
                        if (deadByTimeout)
                        {
                            throw new Exception("Julia timed out:\n" + process.StandardError.ReadToEnd());
                        }
                        if (process.ExitCode != 0)
                        {
                            throw new Exception("Julia encountered a fatal error:\n" + process.StandardError.ReadToEnd());
                        }
                    }
            } finally {
                if (!string.IsNullOrEmpty(tmpFilename) && File.Exists(tmpFilename))
                {
                    File.Delete(tmpFilename);
                }
            }
        }
 public override string Run(string script, bool?localDepot)
 {
     return(AhornHelper.GetJuliaOutput(script, out _, localDepot));
 }
Exemple #4
0
        public override IEnumerator Run(string theme)
        {
            yield return("Initializing...");

            Environment.SetEnvironmentVariable("AHORN_GTK_CSD", null);
            Environment.SetEnvironmentVariable("AHORN_GTK_THEME", null);

            if (!string.IsNullOrEmpty(theme))
            {
                if (theme.EndsWith("|CSD"))
                {
                    theme = theme.Substring(0, theme.Length - 4);
                    Environment.SetEnvironmentVariable("AHORN_GTK_CSD", "1");
                }
                Environment.SetEnvironmentVariable("AHORN_GTK_THEME", theme);
            }

            string tmpFilename = null;

            try {
                using (Process process = AhornHelper.NewJulia(out tmpFilename, @"
env = ENV[""AHORN_ENV""]
globalenv = ENV[""AHORN_GLOBALENV""]

logfilePath = joinpath(mkpath(dirname(globalenv)), ""error.log"")

println(""Logging to "" * logfilePath)

logfile = open(logfilePath, ""w"")
println(logfile, ""Running Ahorn via Olympus."")

flush(stdout)
flush(stderr)

stdoutReal = stdout
(rd, wr) = redirect_stdout()
redirect_stderr(stdout)

@async while !eof(rd)
    data = String(readavailable(rd))
    print(stdoutReal, data)
    flush(stdoutReal)
    print(logfile, data)
    flush(logfile)
end

# Required because Gtk.jl likes to ENV[""GTK_CSD""] = 0 on Windows.
@eval(Base, setindex!(env::EnvDict, v::Int64, k::AbstractString) = k === ""GTK_CSD"" ? false : env[k] = string(v))

csd = get(ENV, ""AHORN_GTK_CSD"", nothing)
if csd !== nothing
    ENV[""GTK_CSD""] = csd
end

theme = get(ENV, ""AHORN_GTK_THEME"", nothing)
if theme !== nothing
    ENV[""GTK_THEME""] = theme
end

using Logging
logger = SimpleLogger(stdout, Logging.Debug)
loggerPrev = Logging.global_logger(logger)

using Pkg
Pkg.activate(env)

install_or_update(url::String, pkg::String) = if ""Ahorn"" ∈ keys(Pkg.Types.Context().env.project.deps)
    println(""Updating $pkg..."")
    Pkg.update(pkg)
else
    println(""Adding $pkg..."")
    Pkg.add(PackageSpec(url = url))
end

if Base.find_package(""Ahorn"") === nothing
    try
        println(""#OLYMPUS# TIMEOUT START"")

        Pkg.instantiate()

        install_or_update(""https://github.com/CelestialCartographers/Maple.git"", ""Maple"")
        install_or_update(""https://github.com/CelestialCartographers/Ahorn.git"", ""Ahorn"")

        Pkg.instantiate()
        Pkg.API.precompile()

        println(""#OLYMPUS# TIMEOUT END"")
    catch e
        println(""FATAL ERROR"")
        println(sprint(showerror, e, catch_backtrace()))
        exit(1)
    end
end

Logging.global_logger(loggerPrev)

using Ahorn
Ahorn.displayMainWindow()
"
                                                              )) {
                    /*/
                     * process.StartInfo.UseShellExecute = true;
                     * process.StartInfo.CreateNoWindow = false;
                     * process.StartInfo.RedirectStandardOutput = false;
                     * process.StartInfo.RedirectStandardError = false;
                     * /**/

                    process.Start();
                    for (string line; (line = process.StandardOutput.ReadLine()) != null;)
                    {
                        yield return(CmdAhornRunJuliaTask.Escape(line, out _));
                    }
                    process.WaitForExit();
                    yield return(process.ExitCode == 0);
                }
            } finally {
                if (!string.IsNullOrEmpty(tmpFilename) && File.Exists(tmpFilename))
                {
                    File.Delete(tmpFilename);
                }
            }
        }