예제 #1
0
        public static string GetFilenameSafe([NotNull] this Process process)
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }
            try {
                var path = GetProcessPathUsingPsApi(process.Id);
                if (path != null)
                {
                    TypoLogging.Write("PS API: " + path);
                    return(path);
                }

                // very slow

                /*path = GetProcessPathUsingManagement(process.Id);
                 * if (path != null) {
                 *  TypoLogging.Write("Management: " + path);
                 *  return path;
                 * }
                 *
                 * TypoLogging.Write("Management failed!");*/

                // won’t work if processes were compiled for different architectures
                path = process.MainModule?.FileName;
                TypoLogging.Write("MainModule.FileName: " + path);
                return(path);
            } catch (Exception e) {
                TypoLogging.Write(e);
                return(null);
            }
        }
예제 #2
0
        private static async Task WaitForExitAsyncDeeperFallback([NotNull] Process process, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }

            TypoLogging.Write("Is there an issue?");

            var processId = process.Id;

            while (true)
            {
                await Task.Delay(300, cancellationToken);

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                try {
                    Process.GetProcessById(processId);
                } catch (ArgumentException) {
                    return;
                }
            }
        }
예제 #3
0
        public static IDisposable WatchFile(string filename, Action reloadAction)
        {
            var reloading = false;

            return(SetWatcher(Path.GetDirectoryName(filename), async s => {
                if (reloading || !FileUtils.ArePathsEqual(s, filename))
                {
                    return;
                }
                reloading = true;

                try {
                    for (var i = 0; i < 3; i++)
                    {
                        try {
                            await Task.Delay(300);
                            reloadAction();
                            break;
                        } catch (IOException e) {
                            TypoLogging.Write(e);
                        }
                    }
                } finally {
                    reloading = false;
                }
            }));
        }
예제 #4
0
 public bool IsInputSupported(string filename)
 {
     try {
         return(!Regex.IsMatch(File.ReadAllText(filename), @"(^|#|//|\n|;)\s*""noinput"""));
     } catch (Exception e) {
         TypoLogging.Write(e);
         return(true);
     }
 }
예제 #5
0
 public static void RestartCurrentApplication()
 {
     try {
         ProcessExtension.Start(MainExecutingFile.Location,
                                Environment.GetCommandLineArgs().Skip(1).ApartFrom(RestartArg)
                                .Where(x => !x.StartsWith("acmanager:", StringComparison.OrdinalIgnoreCase)).Prepend(RestartArg));
         Environment.Exit(0);
     } catch (Exception e) {
         TypoLogging.Write(e);
     }
 }
예제 #6
0
 public Task <string> ExecuteAsync(string filename, string originalText, CancellationToken cancellation)
 {
     try {
         var state = ScriptExtension.CreateState();
         state.Globals["input"] = originalText;
         return(Task.FromResult(state.DoString(GetScript(filename).Replace(@"{INLINED_INPUT}", originalText)).CastToString()));
     } catch (Exception e) {
         TypoLogging.Write(e);
         throw;
     }
 }
예제 #7
0
        private string Execute(string filename, string originalText)
        {
            using (var p = ProcessExtension.Start(
                       _executableName ?? filename,
                       _executableName == null ? null : _arguments.Append(filename),
                       new ProcessStartInfo {
                WorkingDirectory = _workingDirectory ?? ".",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                CreateNoWindow = true,
                StandardOutputEncoding = Encoding.UTF8,
                StandardErrorEncoding = Encoding.UTF8
            })) {
                p.Start();

                using (var writer = new StreamWriter(p.StandardInput.BaseStream, Encoding.UTF8)) {
                    writer.Write(originalText);
                    writer.Close();
                }

                p.WaitForExit();

                var output = p.StandardOutput.ReadToEnd().Trim();
                var error  = p.StandardError.ReadToEnd().Trim();

                if (p.ExitCode != 0)
                {
                    var sb = new StringBuilder();
                    sb.AppendLine("Exit code: " + p.ExitCode);

                    if (output.Length > 0)
                    {
                        sb.Append("\n\n");
                        sb.AppendLine(output);
                    }

                    if (error.Length > 0)
                    {
                        sb.Append("\n\n");
                        sb.AppendLine(error);
                    }

                    TypoLogging.Write(sb.ToString());
                    throw new ExternalInterpreterException(_executableName + " " + _arguments.Append(filename).JoinToString(" "),
                                                           p.ExitCode, output, error);
                }

                p.Close();
                return(output);
            }
        }
예제 #8
0
 public static void ViewInBrowser([CanBeNull] string url)
 {
     if (string.IsNullOrWhiteSpace(url))
     {
         return;
     }
     try {
         Process.Start(url);
     } catch (Exception) {
         TypoLogging.NonFatalErrorNotify("Can’t open link", $"App tried to open: “{url}”");
     }
 }
예제 #9
0
        public static Script CreateState()
        {
            var state = new Script();

            state.Globals["showMsg"] = new Action <string>(m => MessageBox.Show(m));
            state.Globals["report"]  = new Action <string>(m => TypoLogging.NonFatalErrorNotify(m, null));
            state.Globals["log"]     = new Action <string>(m => TypoLogging.Write(m));

            state.Globals["regex"]   = new LuaRegex();
            state.Globals["unicode"] = new LuaUnicode();

            return(state);
        }
예제 #10
0
 private void Reload(string filename)
 {
     if (filename?.EndsWith(".lua", StringComparison.OrdinalIgnoreCase) == false)
     {
         return;
     }
     _lua = Directory.GetFiles(_directory, "*.lua").Select(x => {
         try {
             return(ScriptExtension.CreateState().DoString(File.ReadAllText(x), codeFriendlyName: Path.GetFileName(x)).Function);
         } catch (Exception e) {
             TypoLogging.NonFatalErrorNotify("Can’t execute script", null, e);
             return(null);
         }
     }).NonNull().ToArray();
 }
예제 #11
0
파일: LuaRegex.cs 프로젝트: gro-ove/typo4
 private string ReplaceCallback([CanBeNull] string a, [CanBeNull] string b, [CanBeNull] Closure c, bool ignoreCase)
 {
     return(a == null || b == null || c == null ? null : GetRegex(b, ignoreCase).Replace(a, x => {
         var args = new object[x.Groups.Count];
         for (var i = 0; i < args.Length; i++)
         {
             args[i] = x.Groups[i].Value;
         }
         try {
             return c.Call(args).String;
         } catch (Exception e) {
             TypoLogging.NonFatalErrorNotify("Can’t execute script", null, e);
             return x.Value;
         }
     }));
 }
예제 #12
0
        private static void Release(FileSystemWatcher watcher)
        {
            var found = Watchers.FirstOrDefault(x => ReferenceEquals(x.Value.Watcher, watcher));

            if (found.Value == null)
            {
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
                TypoLogging.Write("Can’t release FSW properly: " + watcher.Path);
            }
            else if (--found.Value.Count == 0)
            {
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
                Watchers.Remove(found.Key);
            }
        }
예제 #13
0
        public async Task <string> ReplaceAsync(int scriptId, string originalText, CancellationToken cancellation)
        {
            try {
                var interpreter = GetInterpreter(scriptId, out var filename);

                TypoLogging.Write("Run command: " + filename + ", orig.=" + originalText + ", iterp.=" + interpreter);
                if (interpreter != null)
                {
                    return(await interpreter.ExecuteAsync(filename, originalText, cancellation));
                }

                TypoLogging.Write($"Supported script not found: {scriptId}");
                return(null);
            } catch (Exception e) {
                TypoLogging.NonFatalErrorNotify("Failed to run a script", "Check if all required libraries are ready.", e);
                return(null);
            }
        }
예제 #14
0
        public static Task WaitForExitAsync([NotNull] this Process process, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }
            try {
                var tcs = new TaskCompletionSource <object>();
                process.EnableRaisingEvents = true;
                process.Exited += (sender, args) => tcs.TrySetResult(null);
                if (cancellationToken != default(CancellationToken))
                {
                    cancellationToken.Register(() => { tcs.TrySetCanceled(); });
                }

                return(tcs.Task);
            } catch (Exception e) {
                TypoLogging.Write(e);
                return(WaitForExitAsyncFallback(process, cancellationToken));
            }
        }
예제 #15
0
        private static string GetProcessPathUsingPsApi(int pid)
        {
            var processHandle = Kernel32.OpenProcess(Kernel32.ProcessAccessFlags.QueryInformation, false, pid);

            if (processHandle == IntPtr.Zero)
            {
                return(null);
            }

            const int lengthSb = 4000;

            try {
                var sb = new StringBuilder(lengthSb);
                return(GetModuleFileNameEx(processHandle, IntPtr.Zero, sb, lengthSb) > 0 ? sb.ToString() : null);
            } catch (Exception e) {
                TypoLogging.Write(e);
                return(null);
            } finally {
                Kernel32.CloseHandle(processHandle);
            }
        }
예제 #16
0
        private static async Task WaitForExitAsyncFallback([NotNull] Process process, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }

            var handle = Kernel32.OpenProcess(Kernel32.ProcessAccessFlags.QueryLimitedInformation | Kernel32.ProcessAccessFlags.Synchronize, false, process.Id);

            if (handle == IntPtr.Zero || handle == new IntPtr(-1))
            {
                await WaitForExitAsyncDeeperFallback(process, cancellationToken);

                return;
            }

            try {
                if (Kernel32.GetExitCodeProcess(handle, out var exitCode) && exitCode != Kernel32.STILL_ACTIVE)
                {
                    return;
                }
                using (var w = new ProcessWrapper.ProcessWaitHandle(handle)) {
                    TypoLogging.Write("Waiting using ProcessWaitHandle…");

                    while (!w.WaitOne(0, false))
                    {
                        await Task.Delay(300, cancellationToken);

                        if (cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }
                    }
                }
            } finally {
                Kernel32.CloseHandle(handle);
            }
        }
예제 #17
0
 public static void Ignore <T>(this Task <T> task)
 {
     task.ContinueWith(x => {
         TypoLogging.Write(x.Exception?.Flatten());
     }, TaskContinuationOptions.OnlyOnFaulted);
 }
예제 #18
0
 public static void Ignore(this Task task)
 {
     task.ContinueWith(x => {
         TypoLogging.Write(x.Exception?.Flatten());
     }, TaskContinuationOptions.NotOnRanToCompletion);
 }