コード例 #1
0
        public static string CallScriptInterpreter(ScriptInterpreterItem scriptInterpreter, string scriptFileFullPath, string inputText)
        {
            string programFullPath = ReplaceVariables(scriptInterpreter.ExecutableProgram, scriptFileFullPath);

            if (!File.Exists(programFullPath))
            {
                throw new Exception(String.Format(I18n._("Executable program \"{0}\" does not exist"), programFullPath));
            }

            string programArguments = ReplaceVariables(scriptInterpreter.CommandLineArguments, scriptFileFullPath);

            ScriptFileEmbeddedConfig scriptFileEmbeddedConfig = ParseScriptFileEmbeddedConfig(scriptFileFullPath);

            EncodingType inputEncodingType = StringUtil.GetEfficientEncodingType(scriptInterpreter.InputEncoding, scriptFileEmbeddedConfig.InputEncoding,
                                                                                 "inputEncoding");

            EncodingType outputEncodingType = StringUtil.GetEfficientEncodingType(scriptInterpreter.OutputEncoding, scriptFileEmbeddedConfig.OutputEncoding,
                                                                                  "outputEncoding");

            Process process = new Process();

            process.StartInfo.FileName               = programFullPath;
            process.StartInfo.Arguments              = programArguments;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.RedirectStandardInput  = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError  = true;

            if (scriptInterpreter.SetPath != null)
            {
                string environmentVariablePath = ReplaceVariables(scriptInterpreter.SetPath, scriptFileFullPath);
                process.StartInfo.EnvironmentVariables["PATH"] = environmentVariablePath;
            }

            int timeout = 3000;

            StringBuilder rawOutputStringBuilder = new StringBuilder();

            AutoResetEvent outputWaitHandle = new AutoResetEvent(false);
            AutoResetEvent errorWaitHandle  = new AutoResetEvent(false);

            process.OutputDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    outputWaitHandle.Set();
                }
                else
                {
                    lock (rawOutputStringBuilder)
                    {
                        rawOutputStringBuilder.AppendLine(e.Data);
                    }
                }
            };

            process.ErrorDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    errorWaitHandle.Set();
                }
                else
                {
                    lock (rawOutputStringBuilder)
                    {
                        rawOutputStringBuilder.AppendLine(e.Data);
                    }
                }
            };

            string stdinString = StringUtil.Encode(inputText, inputEncodingType);

            process.Start();

            process.StandardInput.Write(stdinString);
            process.StandardInput.Close();

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            if (process.WaitForExit(timeout) &&
                outputWaitHandle.WaitOne(timeout) &&
                errorWaitHandle.WaitOne(timeout))
            {
                // Process completed. Check process.ExitCode here.
            }
            else
            {
                // Timed out.
            }

            if (!process.HasExited)
            {
                process.Kill();
            }

            string outputText = StringUtil.Decode(rawOutputStringBuilder.ToString(), outputEncodingType);

            return(outputText);
        }
コード例 #2
0
        private static ScriptFileEmbeddedConfig ParseScriptFileEmbeddedConfig(string scriptFileFullPath)
        {
            ScriptFileEmbeddedConfig result = new ScriptFileEmbeddedConfig();

            // File encoding detect code from http://blog.wudilabs.org/entry/d216f2df/

            bool   isUtf8 = true;
            string headText;

            using (FileStream stream = new FileStream(scriptFileFullPath, FileMode.Open, FileAccess.Read,
                                                      FileShare.Read, 8192, FileOptions.SequentialScan))
            {
                long   length = Math.Min(stream.Length, 8192);
                byte[] bytes  = new byte[length];
                byte   first;
                long   pos = 0;
                while (pos < length)
                {
                    first = bytes[pos++] = (byte)stream.ReadByte();
                    if (first < 192)
                    {
                    }
                    else if (first < 224)
                    {
                        if ((length - pos > 1) &&
                            (bytes[pos++] = (byte)stream.ReadByte()) < 128)
                        {
                            isUtf8 = false;
                            break;
                        }
                    }
                    else if (first < 240)
                    {
                        if ((length - pos > 2) &&
                            !((bytes[pos++] = (byte)stream.ReadByte()) > 127 &&
                              (bytes[pos++] = (byte)stream.ReadByte()) > 127))
                        {
                            isUtf8 = false;
                            break;
                        }
                    }
                    else
                    {
                        if ((length - pos > 3) &&
                            !((bytes[pos++] = (byte)stream.ReadByte()) > 127 &&
                              (bytes[pos++] = (byte)stream.ReadByte()) > 127 &&
                              (bytes[pos++] = (byte)stream.ReadByte()) > 127))
                        {
                            isUtf8 = false;
                            break;
                        }
                    }
                }

                headText = isUtf8 ? Encoding.UTF8.GetString(bytes) : Encoding.Default.GetString(bytes);
            }

            headText = headText.Replace("\r\n", "\n").Replace("\r", "");

            int iniSectionLinePos = headText.IndexOf("\n[ClipboardAutoProcessor]\n");

            if (iniSectionLinePos == -1)
            {
                if (headText.IndexOf("[ClipboardAutoProcessor]\n") == 0)
                {
                    iniSectionLinePos = 0;
                }
            }
            else
            {
                iniSectionLinePos++;    // skip leading '\n'
            }

            if (iniSectionLinePos == -1)
            {
                return(result);
            }

            StringBuilder embeddedIniStringBuilder = new StringBuilder();

            string[] lines = headText.Substring(iniSectionLinePos).Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i].Trim();

                if (line.Length == 0)
                {
                    break;
                }

                char firstChar = line[0];
                if ((firstChar != '[') &&
                    (firstChar != '#') &&
                    !char.IsLetter(firstChar))
                {
                    break;
                }

                embeddedIniStringBuilder.AppendLine(line);
            }

            if (lines.Length == 0)
            {
                return(result);
            }

            IniOptions iniOptions = new IniOptions()
            {
                Encoding = isUtf8 ? Encoding.UTF8 : Encoding.Default,
                KeySpaceAroundDelimiter = true,
                CommentStarter          = IniCommentStarter.Hash // to prevent MadMilkman.Ini from treating value after semicolon as comment
            };

            IniFile iniFile = new IniFile(iniOptions);

            iniFile.Load(new StringReader(embeddedIniStringBuilder.ToString()));

            result.InputEncoding  = iniFile.Sections["ClipboardAutoProcessor"]?.Keys["inputEncoding"]?.Value;
            result.OutputEncoding = iniFile.Sections["ClipboardAutoProcessor"]?.Keys["outputEncoding"]?.Value;

            return(result);
        }