예제 #1
0
        internal static Promise <RequirementsCheckResult> CheckRequirementsAsync()
        {
            if (string.IsNullOrEmpty(Settings.CharonExecutablePath) || !File.Exists(Settings.CharonExecutablePath))
            {
                return(Promise.FromResult(RequirementsCheckResult.MissingExecutable));
            }

            var additionalChecks = new List <Promise <RequirementsCheckResult> >();

            if (RuntimeInformation.IsWindows)
            {
                if (DotNetRuntimeInformation.GetVersion() == null && (string.IsNullOrEmpty(MonoRuntimeInformation.MonoPath) ||
                                                                      File.Exists(MonoRuntimeInformation.MonoPath) == false))
                {
                    return(Promise.FromResult(RequirementsCheckResult.MissingRuntime));
                }
            }
            else
            {
                if (string.IsNullOrEmpty(MonoRuntimeInformation.MonoPath) || File.Exists(MonoRuntimeInformation.MonoPath) == false)
                {
                    return(Promise.FromResult(RequirementsCheckResult.MissingRuntime));
                }

                additionalChecks.Add(GetMonoVersionAsync().ContinueWith(getMonoVersion =>
                {
                    if (getMonoVersion.HasErrors || getMonoVersion.GetResult() == null || getMonoVersion.GetResult() < MinimalMonoVersion)
                    {
                        return(RequirementsCheckResult.MissingRuntime);
                    }
                    else
                    {
                        return(RequirementsCheckResult.Ok);
                    }
                }));
            }

            if (!string.IsNullOrEmpty(Settings.Current.EditorVersion))
            {
                additionalChecks.Add(GetVersionAsync().ContinueWith(getCharonVersion =>
                {
                    if (getCharonVersion.HasErrors || getCharonVersion.GetResult() == null ||
                        getCharonVersion.GetResult().ToString() != Settings.Current.EditorVersion)
                    {
                        return(RequirementsCheckResult.WrongVersion);
                    }
                    else
                    {
                        return(RequirementsCheckResult.Ok);
                    }
                }));
            }

            if (additionalChecks.Count == 0)
            {
                return(Promise.FromResult(RequirementsCheckResult.Ok));
            }
            else
            {
                return(Promise.WhenAll(additionalChecks.ToArray())
                       .ContinueWith(results => results.GetResult().FirstOrDefault(r => r != RequirementsCheckResult.Ok)));
            }
        }
예제 #2
0
        private static IEnumerable RunAsync(RunOptions options)
        {
            yield return(null);

            var isDotNetInstalled = false;

            if (RuntimeInformation.IsWindows)
            {
                isDotNetInstalled = DotNetRuntimeInformation.GetVersion() != null;
            }

            if (options.RequireDotNetRuntime && isDotNetInstalled == false)
            {
                if (string.IsNullOrEmpty(MonoRuntimeInformation.MonoPath))
                {
                    throw new InvalidOperationException("No .NET runtime found on machine.");
                }

                options.StartInfo.Arguments = RunOptions.ConcatenateArguments(options.StartInfo.FileName) + " " + options.StartInfo.Arguments;
                options.StartInfo.FileName  = MonoRuntimeInformation.MonoPath;
            }

            if (options.CaptureStandardError)
            {
                options.StartInfo.RedirectStandardError = true;
            }
            if (options.CaptureStandardOutput)
            {
                options.StartInfo.RedirectStandardOutput = true;
            }

            if (Settings.Current.Verbose)
            {
                UnityEngine.Debug.Log(string.Format("Starting process '{0}' at '{1}' with arguments '{2}' and environment variables '{3}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments, ConcatenateDictionaryValues(options.StartInfo.EnvironmentVariables)));
            }

            var processStarted = DateTime.UtcNow;
            var timeout        = options.ExecutionTimeout;

            if (timeout <= TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            var process = Process.Start(options.StartInfo);

            if (process == null)
            {
                throw new InvalidOperationException("Unknown process start error.");
            }

            var result = new RunResult(options, process);

            if (options.WaitForExit == false)
            {
                //if (Settings.Current.Verbose)
                //	UnityEngine.Debug.Log(string.Format("Yielding started process '{0}' at '{1}' with arguments '{2}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments));
                yield return(result);

                yield break;
            }

            var hasExited = false;

            while (hasExited == false)
            {
                if (DateTime.UtcNow - processStarted > timeout)
                {
                    throw new TimeoutException();
                }

                try
                {
                    process.Refresh();
                    hasExited = process.HasExited;
                }
                catch (InvalidOperationException)
                {
                    // ignored
                }
                catch (System.ComponentModel.Win32Exception)
                {
                    // ignored
                }
                yield return(Promise.Delayed(TimeSpan.FromMilliseconds(50)));
            }

            processStarted = DateTime.UtcNow;
            timeout        = options.TerminationTimeout;
            if (timeout <= TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            while (result.HasPendingData)
            {
                if (DateTime.UtcNow - processStarted > timeout)
                {
                    throw new TimeoutException();
                }

                yield return(Promise.Delayed(TimeSpan.FromMilliseconds(50)));
            }

            result.ExitCode = process.ExitCode;

            if (Settings.Current.Verbose)
            {
                UnityEngine.Debug.Log(string.Format("Process #{1} '{0}' has exited with code {2}.", options.StartInfo.FileName, result.ProcessId, result.ExitCode));
            }

            yield return(result);
        }