我正在寻找在Linux机器中执行Mono(C#)的进程,但我需要它在我的.exe退出后继续运行。我正在尝试使用nohup来做到这一点,但到目前为止还没有取得任何成功。这是我现在的代码:
void Execute(string command, string commandPath, string arguments, bool nohup = false)
{
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = nohup ? "sh" : Path.Combine(commandPath, script),
Arguments = nohup ? "nohup " + Path.Combine(commandPath, script) + " " + arguments + " &" : arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UserName = System.Environment.UserName
};
using (Process process = Process.Start(startInfo))
{ // Monitor for exit}
}
所以我正在检查nohup参数,如果是,我执行shell并发送完整命令(例如:nohup /path/to/my/command <args> &
)。我收到的错误是/path/to/my/command cannot execute binary file
。
我想到的另一件事是打开sh进程然后将完整的nohup命令发送到标准输入,但为了做到这一点,我必须重构相当多的代码,所以如果有办法没有这个我做我想要的,我会走那条路。
那么......在Linux环境(Mono)中使用nohup在父进程死后保持活着的C#中执行进程的最佳方法是什么?
答案 0 :(得分:0)
我收到错误消息,指出/ path / to / my / command无法执行 二进制文件。
在这种情况下,我会将CreateNoWindow更改为true,不要重定向IO并查看您在创建的shell中获得的内容以便调试...
到目前为止正在创建一个后台进程,一种方法是创建守护进程并有一个方法来读取/写入信息(网络端口,文件日志等),但只是像你尝试工作一样启动后台任务精细。
这是一个使用您的代码作为起点的快速黑客/示例。而不是使用Process,我只是系统执行命令,在这种情况下是一个查找。由于它在后台运行,我运行一个进程来计算1秒后日志文件中的行数,并在退出时得到一个提示来终止该后台查找过程......
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace nohub.process.exec
{
class MainClass
{
[DllImport ("libc")]
private static extern int system (string exec);
private static string logfile = Path.GetTempFileName ();
static void Execute (string command, string commandPath, string arguments, bool nohup = false)
{
if (!nohup) {
var startInfo = new ProcessStartInfo () {
FileName = Path.Combine (commandPath, command),
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UserName = System.Environment.UserName
};
using (Process process = Process.Start (startInfo)) { // Monitor for exit}
process.WaitForExit ();
using (var output = process.StandardOutput) {
Console.Write ("Results: {0}", output.ReadLine ());
}
}
} else {
system ("nohup " + Path.Combine (commandPath, command) + " " + arguments + " 2>&1 > " + logfile + " & ");
}
}
public static void Main (string[] args)
{
Console.WriteLine ("Hello Stack Overflow");
Console.WriteLine ("Temp file: {0}", logfile);
Execute ("find", "", "/", true);
Thread.Sleep (1000);
Execute ("wc", "", "-l " + logfile, false);
Console.Write ("\nLet find continue? [y/n]");
if ((Console.ReadKey (false)).KeyChar == 'y')
system ("killall find");
}
}
}