您的位置:首页 > 编程语言 > C#

C#启动外部exe进程

2016-10-14 19:38 274 查看
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.CommandL
c075
ine)
{
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();

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c#