protected override CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (fileNames == null) { throw new ArgumentNullException(nameof(fileNames)); } CompilerResults results = new CompilerResults(options.TempFiles); Process vbnc = new Process(); string vbnc_output = ""; string[] vbnc_output_lines; // FIXME: these lines had better be platform independent. if (Path.DirectorySeparatorChar == '\\') { vbnc.StartInfo.FileName = MonoToolsLocator.Mono; vbnc.StartInfo.Arguments = MonoToolsLocator.VBCompiler + ' ' + BuildArgs(options, fileNames); } else { vbnc.StartInfo.FileName = MonoToolsLocator.VBCompiler; vbnc.StartInfo.Arguments = BuildArgs(options, fileNames); } //Console.WriteLine (vbnc.StartInfo.Arguments); vbnc.StartInfo.CreateNoWindow = true; vbnc.StartInfo.UseShellExecute = false; vbnc.StartInfo.RedirectStandardOutput = true; try { vbnc.Start(); } catch (Exception e) { Win32Exception exc = e as Win32Exception; if (exc != null) { throw new SystemException(String.Format("Error running {0}: {1}", vbnc.StartInfo.FileName, Win32Exception.GetErrorMessage(exc.NativeErrorCode))); } throw; } try { vbnc_output = vbnc.StandardOutput.ReadToEnd(); vbnc.WaitForExit(); } finally { results.NativeCompilerReturnValue = vbnc.ExitCode; vbnc.Close(); } bool loadIt = true; if (results.NativeCompilerReturnValue == 1) { loadIt = false; vbnc_output_lines = vbnc_output.Split(Environment.NewLine.ToCharArray()); foreach (string error_line in vbnc_output_lines) { CompilerError error = CreateErrorFromString(error_line); if (null != error) { results.Errors.Add(error); } } } if ((loadIt == false && !results.Errors.HasErrors) || // Failed, but no errors? Probably couldn't parse the compiler output correctly. (results.NativeCompilerReturnValue != 0 && results.NativeCompilerReturnValue != 1)) // Neither success (0), nor failure (1), so it crashed. { // Show the entire output as one big error message. loadIt = false; CompilerError error = new CompilerError(string.Empty, 0, 0, "VBNC_CRASH", vbnc_output); results.Errors.Add(error); } ; if (loadIt) { if (options.GenerateInMemory) { using (FileStream fs = File.OpenRead(options.OutputAssembly)) { byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); results.CompiledAssembly = Assembly.Load(buffer, null); fs.Close(); } } else { results.CompiledAssembly = Assembly.LoadFrom(options.OutputAssembly); results.PathToAssembly = options.OutputAssembly; } } else { results.CompiledAssembly = null; } return(results); }
bool StartWithCreateProcess(ProcessStartInfo startInfo) { if (startInfo.StandardOutputEncoding != null && !startInfo.RedirectStandardOutput) { throw new InvalidOperationException(SR.GetString(SR.StandardOutputEncodingNotAllowed)); } if (startInfo.StandardErrorEncoding != null && !startInfo.RedirectStandardError) { throw new InvalidOperationException(SR.GetString(SR.StandardErrorEncodingNotAllowed)); } if (this.disposed) { throw new ObjectDisposedException(GetType().Name); } var procInfo = new ProcInfo(); if (startInfo.HaveEnvVars) { List <string> envVariables = null; StringBuilder sb = null; foreach (DictionaryEntry de in startInfo.EnvironmentVariables) { if (de.Value == null) { continue; } if (envVariables == null) { envVariables = new List <string> (); } if (sb == null) { sb = new StringBuilder(); } else { sb.Clear(); } sb.Append((string)de.Key); sb.Append('='); sb.Append((string)de.Value); envVariables.Add(sb.ToString()); } procInfo.envVariables = envVariables?.ToArray(); } MonoIOError error; IntPtr stdin_read = IntPtr.Zero, stdin_write = IntPtr.Zero; IntPtr stdout_read = IntPtr.Zero, stdout_write = IntPtr.Zero; IntPtr stderr_read = IntPtr.Zero, stderr_write = IntPtr.Zero; try { if (startInfo.RedirectStandardInput) { CreatePipe(out stdin_read, out stdin_write, true); } else { stdin_read = MonoIO.ConsoleInput; stdin_write = IntPtr.Zero; } if (startInfo.RedirectStandardOutput) { CreatePipe(out stdout_read, out stdout_write, false); } else { stdout_read = IntPtr.Zero; stdout_write = MonoIO.ConsoleOutput; } if (startInfo.RedirectStandardError) { CreatePipe(out stderr_read, out stderr_write, false); } else { stderr_read = IntPtr.Zero; stderr_write = MonoIO.ConsoleError; } FillUserInfo(startInfo, ref procInfo); // // FIXME: For redirected pipes we need to send descriptors of // stdin_write, stdout_read, stderr_read to child process and // close them there (fork makes exact copy of parent's descriptors) // if (!CreateProcess_internal(startInfo, stdin_read, stdout_write, stderr_write, ref procInfo)) { throw new Win32Exception(-procInfo.pid, "ApplicationName='" + startInfo.FileName + "', CommandLine='" + startInfo.Arguments + "', CurrentDirectory='" + startInfo.WorkingDirectory + "', Native error= " + Win32Exception.GetErrorMessage(-procInfo.pid)); } } catch { if (startInfo.RedirectStandardInput) { if (stdin_read != IntPtr.Zero) { MonoIO.Close(stdin_read, out error); } if (stdin_write != IntPtr.Zero) { MonoIO.Close(stdin_write, out error); } } if (startInfo.RedirectStandardOutput) { if (stdout_read != IntPtr.Zero) { MonoIO.Close(stdout_read, out error); } if (stdout_write != IntPtr.Zero) { MonoIO.Close(stdout_write, out error); } } if (startInfo.RedirectStandardError) { if (stderr_read != IntPtr.Zero) { MonoIO.Close(stderr_read, out error); } if (stderr_write != IntPtr.Zero) { MonoIO.Close(stderr_write, out error); } } throw; } finally { if (procInfo.Password != IntPtr.Zero) { Marshal.ZeroFreeBSTR(procInfo.Password); procInfo.Password = IntPtr.Zero; } } SetProcessHandle(new SafeProcessHandle(procInfo.process_handle, true)); SetProcessId(procInfo.pid); #pragma warning disable 618 if (startInfo.RedirectStandardInput) { MonoIO.Close(stdin_read, out error); #if MOBILE var stdinEncoding = Encoding.Default; #else var stdinEncoding = Console.InputEncoding; #endif standardInput = new StreamWriter(new FileStream(stdin_write, FileAccess.Write, true, 8192), stdinEncoding) { AutoFlush = true }; } if (startInfo.RedirectStandardOutput) { MonoIO.Close(stdout_write, out error); Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.OutputEncoding; standardOutput = new StreamReader(new FileStream(stdout_read, FileAccess.Read, true, 8192), stdoutEncoding, true); } if (startInfo.RedirectStandardError) { MonoIO.Close(stderr_write, out error); Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.OutputEncoding; standardError = new StreamReader(new FileStream(stderr_read, FileAccess.Read, true, 8192), stderrEncoding, true); } #pragma warning restore return(true); }
private CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (fileNames == null) { throw new ArgumentNullException(nameof(fileNames)); } CompilerResults results = new CompilerResults(options.TempFiles); Process mcs = new Process(); // FIXME: these lines had better be platform independent. if (Path.DirectorySeparatorChar == '\\') { mcs.StartInfo.FileName = MonoToolsLocator.Mono; mcs.StartInfo.Arguments = "\"" + MonoToolsLocator.McsCSharpCompiler + "\" "; } else { mcs.StartInfo.FileName = MonoToolsLocator.McsCSharpCompiler; } mcs.StartInfo.Arguments += BuildArgs(options, fileNames, _provOptions); var mcsOutMutex = new Mutex(); /* * string monoPath = Environment.GetEnvironmentVariable ("MONO_PATH"); * if (monoPath != null) * monoPath = String.Empty; * * string privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath; * if (privateBinPath != null && privateBinPath.Length > 0) * monoPath = String.Format ("{0}:{1}", privateBinPath, monoPath); * * if (monoPath.Length > 0) { * StringDictionary dict = mcs.StartInfo.EnvironmentVariables; * if (dict.ContainsKey ("MONO_PATH")) * dict ["MONO_PATH"] = monoPath; * else * dict.Add ("MONO_PATH", monoPath); * } */ /* * reset MONO_GC_PARAMS - we are invoking compiler possibly with another GC that * may not handle some of the options causing compilation failure */ mcs.StartInfo.EnvironmentVariables ["MONO_GC_PARAMS"] = String.Empty; mcs.StartInfo.CreateNoWindow = true; mcs.StartInfo.UseShellExecute = false; mcs.StartInfo.RedirectStandardOutput = true; mcs.StartInfo.RedirectStandardError = true; mcs.ErrorDataReceived += new DataReceivedEventHandler((sender, args) => { if (args.Data != null) { mcsOutMutex.WaitOne(); results.Output.Add(args.Data); mcsOutMutex.ReleaseMutex(); } }); // Use same text decoder as mcs and not user set values in Console mcs.StartInfo.StandardOutputEncoding = mcs.StartInfo.StandardErrorEncoding = Encoding.UTF8; try { mcs.Start(); } catch (Exception e) { Win32Exception exc = e as Win32Exception; if (exc != null) { throw new SystemException(String.Format("Error running {0}: {1}", mcs.StartInfo.FileName, Win32Exception.GetErrorMessage(exc.NativeErrorCode))); } throw; } try { mcs.BeginOutputReadLine(); mcs.BeginErrorReadLine(); mcs.WaitForExit(); results.NativeCompilerReturnValue = mcs.ExitCode; } finally { mcs.CancelErrorRead(); mcs.CancelOutputRead(); mcs.Close(); } bool loadIt = true; foreach (string error_line in results.Output) { CompilerError error = CreateErrorFromString(error_line); if (error != null) { results.Errors.Add(error); if (!error.IsWarning) { loadIt = false; } } } if (results.Output.Count > 0) { results.Output.Insert(0, mcs.StartInfo.FileName + " " + mcs.StartInfo.Arguments + Environment.NewLine); } if (loadIt) { if (!File.Exists(options.OutputAssembly)) { StringBuilder sb = new StringBuilder(); foreach (string s in results.Output) { sb.Append(s + Environment.NewLine); } throw new Exception("Compiler failed to produce the assembly. Output: '" + sb.ToString() + "'"); } if (options.GenerateInMemory) { using (FileStream fs = File.OpenRead(options.OutputAssembly)) { byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); results.CompiledAssembly = Assembly.Load(buffer, null); fs.Close(); } } else { // Avoid setting CompiledAssembly right now since the output might be a netmodule results.PathToAssembly = options.OutputAssembly; } } else { results.CompiledAssembly = null; } return(results); }