声明
- windows平台
- 因脚本较多,有点混乱,并且bat文件多了执行起来也分不清谁是谁,所以集中管理有点必要,网上找了几下没瞅见,自己杜撰一个脚本宿主。
- IIS作为宿主托管项目,日志记入文件,很强大。但是部分脚本程序还是实时显示结果比较舒服。
原理
- 主程序管理脚本进程,并监听脚本输入输出。
- 进程和脚本都需要处理好当前工作路径。
- 输出结果应该需要保留一定数量,这里用了Queue。
- 注意:对于bat启动的第三方程序,可能影响对缓存属性敏感的输出。例如python xxx.py 可能需要改成python -u xxx.py,(-u : force the binary I/O layers of stdout and stderr to be unbuffered;)。
部分代码
写法比较偷懒,为了解释有改动
- 启动进程
没什么特别的
主要需要设置StartInfo中的几条信息
需要监听 StandardError,StandardOutput
string fullPath = "xxx"
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = fullPath;
try
{
process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(fullPath);
}
catch
{
}
// 必须禁用操作系统外壳程序
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = false;
process.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
- 结束进程
网上都是这个,就不客气了
public static void KillProcessAndChildren(int pid)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
try
{
Process proc = Process.GetProcessById(pid);
proc.Kill();
}
catch (Exception)
{
/* process already exited */
}
}
- 其它
bat使用当前目录:PUSHD
bat调用bat:call xxx.bat
bat调用python:python -u xxx.py
bat调用虚拟环境python:
PUSHD
call env\Scripts\activate
PUSHD
python -u start.py
cmd
另外,乱七八糟的代码移步,Release/bin目录下PyHost.exe可以直接使用
git参考
补充(2019.4.10)
不适合需要大量输出的脚本,否则卡给你看
网友评论