1. 程式人生 > >C#啟動外部exe程序

C#啟動外部exe程序

1、定義介面

//定義一個啟動程序需要的引數的介面
    public interface IProcessArgs
    {
    //可執行檔案
        string Exefile
        {
            get;
        }
//啟動exe需要的引數
        string Parameter
        {
            get;
        }
//命令列就是exe加上引數,如"haha.exe -help"
        string CommandLine
        {
            get;
        }
//是否需要重定向程序的標準輸入輸出流
bool Redirect { get; } //是否隱藏命令列視窗 bool HidenWindow { get; } }

2、簡單實現介面

    public class ProcessArgs : IProcessArgs
    {
        public string Name { get; protected set; }

        public string Exefile
        {
            get
; protected set; } public string Parameter { get; protected set; } public string CommandLine { get; protected set; } protected bool _redirect = true; public bool Redirect { get
{ return _redirect; } set { _redirect = value; } } protected bool _hidenWindow = true; public bool HidenWindow { get { return _hidenWindow; } set { _hidenWindow = value; } } }

3、具體的程序引數

    public class VisualStudioProcessArgs : ProcessArgs
    {

        public VisualStudioProcessArgs()
        {
            Name = "VS2010";
            Exefile = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe";
            CommandLine = string.Format(GlobalConsts.CommandLineTmpl, Exefile, configFile);
            Parameter = string.Format(GlobalConsts.CommandLineParameterTmpl, configFile);
        }
    }

4、定義一個程序Manager

       public class ProcessFacade<T>
        where T:IProcessTrait, new()
    {
        private static T ProcessTrait = new T(); 
        public static Process MainProcess
        {
            get;
            private set;
        }

        public static bool IsAlive
        {
            get;
            set;
        }

        public static void Start()
        {
            var info = new ProcessStartInfo(ProcessArgs.Exefile);

            info.UseShellExecute = false; 
            info.Arguments = ProcessArgs.Parameter;
            //注意:如果需要重定向程序的標準輸入輸出流,則info.UseShellExecute一定是false,看附錄
            if (ProcessArgs.Redirect) { 
                info.RedirectStandardInput = true;
                info.RedirectStandardOutput = true;
                info.RedirectStandardError = true;
            }
            info.CreateNoWindow = ProcessTrait.HidenWindow;
//看看啟動的程序是不是已經存在,如果存在就把他kill掉
            BeSureProcessBeKilled();

            var p = Process.Start(info);

            /// 啟動失敗
            if (p.HasExited)
            {
                string pMsg = string.Format("Process [{0}] {1}", ProcessArgs.Exefile, " has exited!");
                System.Windows.MessageBox.Show(pMsg);
            }

            p.EnableRaisingEvents = true;
            MainProcess = p;

            if (ProcessArgs.Redirect)
            {
                new Thread(() =>
                {
                    try 
                    {
                        //read redirect thread
                        var outReadThread = new Thread(() =>
                        {
                            var outStream = p.StandardOutput;
                            while (!outStream.EndOfStream)
                            {
                                var msg = outStream.ReadLine();
                                Console.WriteLine(MainProcess.Id,msg);
                            }
                        });
                        outReadThread.Start();

                        //error redirect thread
                        var errorReadThread = new Thread(() =>
                        {
                            var errorStream = p.StandardError;
                            while (!errorStream.EndOfStream)
                            {
                                var msg = errorStream.ReadLine();
                                Console.WriteLine(MainProcess.Id, msg);
                            }
                        });
                        errorReadThread.Start();

                        outReadThread.Join();
                        errorReadThread.Join();
                    }
                    catch(Exception exc)
                    {
                        Console.WriteLine("sorrry, console out and console error out meet some trouble: " + exc.Message);
                    }
                }).Start();
            }

        }

        private static void BeSureProcessBeKilled()
        {
            var processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(ProcessTrait.Exefile));
            foreach (var process in processes)
            {
                try
                {
                    using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id))
                    {
                        foreach (ManagementObject one in searcher.Get())
                        {
                            if (one["CommandLine"] + "" == ProcessTrait.CommandLine)
                            {
                                process.EnableRaisingEvents = false;
                                if (process.HasExited)
                                {

                                }
                                process.Kill();
                                process.WaitForExit();
                                break;
                            }
                        }
                    }
                }
                catch (Win32Exception ex)
                {
                    if ((uint)ex.ErrorCode != 0x80004005)
                    {
                        throw;
                    }
                }
            }
        }

        public static void Stop()
        {
            //if(!MainProcess.HasExited) MainProcess.Kill();
            BeSureProcessBeKilled();
        }

        public static void Restart()
        {
            Stop();
            Start();
        }


        private static EventHandler _exited;
        public static void SetExited(EventHandler exited)
        {
            _exited = exited;
            if (exited != null)
            {
                if (MainProcess.HasExited)
                    MainProcess.Exited -= _exited;
                MainProcess.Exited += exited;
                _exited = exited;
            }
            else
            {
                if (MainProcess.HasExited)
                    MainProcess.Exited -= _exited;
            }
        }
    }

5、啟動程序
ProcessFacade.Start();

6、總結
前面整這個多,實際上是為了可擴充套件和便於管理,實際上最精華的是:

 Process myProcess = new Process(); 
 myProcess.StartInfo.FileName = "Sort.exe";
 myProcess.StartInfo.UseShellExecute = false;
 myProcess.StartInfo.RedirectStandardInput = true;

 myProcess.Start();

7、附錄

using System;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;

namespace Process_StandardInput_Sample
{
   class StandardInputTest
   {
      static void Main()
      {
         Console.WriteLine("Ready to sort one or more text lines...");

         // Start the Sort.exe process with redirected input.
         // Use the sort command to sort the input text.
         Process myProcess = new Process();

         myProcess.StartInfo.FileName = "Sort.exe";
         myProcess.StartInfo.UseShellExecute = false;
         myProcess.StartInfo.RedirectStandardInput = true;

         myProcess.Start();

         StreamWriter myStreamWriter = myProcess.StandardInput;

         // Prompt the user for input text lines to sort. 
         // Write each line to the StandardInput stream of
         // the sort command.
         String inputText;
         int numLines = 0;
         do 
         {
            Console.WriteLine("Enter a line of text (or press the Enter key to stop):");

            inputText = Console.ReadLine();
            if (inputText.Length > 0)
            {
               numLines ++;
               myStreamWriter.WriteLine(inputText);
            }
         } while (inputText.Length != 0);


         // Write a report header to the console.
         if (numLines > 0)
         {
            Console.WriteLine(" {0} sorted text line(s) ", numLines);
            Console.WriteLine("------------------------");
         }
         else 
         {
            Console.WriteLine(" No input was sorted");
         }

         // End the input stream to the sort command.
         // When the stream closes, the sort command
         // writes the sorted text lines to the 
         // console.
         myStreamWriter.Close();


         // Wait for the sort process to write the sorted text lines.
         myProcess.WaitForExit();
         myProcess.Close();

      }
   }
}