Mono.CSharp.CSharpCodeCompiler.CompileFromFileBatch C# (CSharp) Method

CompileFromFileBatch() private method

private CompileFromFileBatch ( CompilerParameters options, string fileNames ) : CompilerResults
options System.CodeDom.Compiler.CompilerParameters
fileNames string
return System.CodeDom.Compiler.CompilerResults
		private CompilerResults CompileFromFileBatch (CompilerParameters options, string[] fileNames)
		{
			if (null == options)
				throw new ArgumentNullException("options");
			if (null == fileNames)
				throw new ArgumentNullException("fileNames");

			CompilerResults results=new CompilerResults(options.TempFiles);
			Process mcs=new Process();

#if !NET_2_0
			string mcs_output;
			string mcs_stdout;
			string[] mcsOutput;
#endif
			
			// FIXME: these lines had better be platform independent.
			if (Path.DirectorySeparatorChar == '\\') {
				mcs.StartInfo.FileName = windowsMonoPath;
				mcs.StartInfo.Arguments = "\"" + windowsMcsPath + "\" " +
#if NET_2_0
					BuildArgs (options, fileNames, ProviderOptions);
#else
					BuildArgs (options, fileNames);
#endif
			} else {
#if NET_2_0
				// FIXME: This is a temporary hack to make code genaration work in 2.0
				mcs.StartInfo.FileName="gmcs";
				mcs.StartInfo.Arguments=BuildArgs(options, fileNames, ProviderOptions);
#else
				mcs.StartInfo.FileName="mcs";
				mcs.StartInfo.Arguments=BuildArgs(options, fileNames);
#endif
			}

#if NET_2_0
			mcsOutput = new StringCollection ();
			mcsOutMutex = new Mutex ();
#endif

			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);
			}
			
			mcs.StartInfo.CreateNoWindow=true;
			mcs.StartInfo.UseShellExecute=false;
			mcs.StartInfo.RedirectStandardOutput=true;
			mcs.StartInfo.RedirectStandardError=true;
#if NET_2_0
			mcs.ErrorDataReceived += new DataReceivedEventHandler (McsStderrDataReceived);
#endif
			
			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.W32ErrorMessage (exc.NativeErrorCode)));
				}
				throw;
			}

			try {
#if NET_2_0
				mcs.BeginOutputReadLine ();
				mcs.BeginErrorReadLine ();
#else
				// If there are a few kB in stdout, we might lock
				mcs_output=mcs.StandardError.ReadToEnd();
				mcs_stdout=mcs.StandardOutput.ReadToEnd ();
#endif
				mcs.WaitForExit();
				
				results.NativeCompilerReturnValue = mcs.ExitCode;
			} finally {
#if NET_2_0
				mcs.CancelErrorRead ();
				mcs.CancelOutputRead ();
#endif

				mcs.Close();
			}

#if NET_2_0
			StringCollection sc = mcsOutput;
#else
			mcsOutput = mcs_output.Split (System.Environment.NewLine.ToCharArray ());
			StringCollection sc = new StringCollection ();
#endif
		       
 			bool loadIt=true;
			foreach (string error_line in mcsOutput) {
#if !NET_2_0
				sc.Add (error_line);
#endif
				CompilerError error = CreateErrorFromString (error_line);
				if (error != null) {
					results.Errors.Add (error);
					if (!error.IsWarning)
						loadIt = false;
				}
			}
			
			if (sc.Count > 0) {
				sc.Insert (0, mcs.StartInfo.FileName + " " + mcs.StartInfo.Arguments + Environment.NewLine);
				results.Output = sc;
			}

			if (loadIt) {
				if (!File.Exists (options.OutputAssembly)) {
					StringBuilder sb = new StringBuilder ();
					foreach (string s in sc)
						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, options.Evidence);
						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;
		}