C#啟動外部exe程序
阿新 • • 發佈:2019-02-05
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();
}
}
}