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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }