我正在尝试为lftp linux进程添加Windows本机通知。 为此,我试图从c#控制台应用程序启动命令以捕获lftp的状态。 问题是,如果我从c#启动它与从bash运行它,我没有相同的输出。
我有一个帮助器类来进行命令行调用:
public static class ShellHelper
{
public static void Bash(this string cmd)
{
var escapedArgs = cmd.Replace("\"", "\\\"");
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "C:/cygwin64/bin/sh.exe",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
StandardOutputEncoding = Encoding.UTF8,
WindowStyle = ProcessWindowStyle.Hidden,
}
};
process.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutput);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
private static void ErrorOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine("Error: " + e.Data);
}
}
private static void ReadOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine(e.Data);
}
}
}
我的电话是:
ShellHelper.Bash("unbuffer lftp -p 22 -u login,password sftp://XXXXXXXXX -e \"set mirror:use-pget-n 20; mirror --parallel=3 -c -P5 /home29/qualinost/files/tests ./tests; quit; \"");
这是从bash启动命令时获得的预期输出
cd `/home29/qualinost/files/tests' [Connecting...]
cd `/home29/qualinost/files/tests' [Connected]
`Kaamelott - S01E17 - Le Signe.mkv', got 0 of 48941955 (0%)
............................................................................................................................................................................................................................................
[A`Kaamelott - S01E17 - Le Signe.mkv', got 32768 of 48941955 (0%)
................................................................................ ................................................................................ .............................................................................
[A`Kaamelott - S01E17 - Le Signe.mkv', got 131072 of 48941955 (0%)
................................................................................ ................................................................................ .............................................................................
[A`Kaamelott - S01E17 - Le Signe.mkv', got 458752 of 48941955 (0%) 235.7K/s
oo.............................................................................. ................................................................................ .............................................................................
[A`Kaamelott - S01E17 - Le Signe.mkv', got 720896 of 48941955 (1%) 265.0K/s
这就是我从c#启动相同命令时得到的:
cd `/home29/qualinost/files/tests' [Connecting...]
cd `/home29/qualinost/files/tests' [Connected]
`...1E17 - Le Signe.mkv', got 0 of 48941955 (0%)
`...1E17 - Le Signe.mkv', got 131072 of 48941955(0%)..........................
`...1E17 - Le Signe.mkv', got 917504 of 48941955 (1%) 598.5K/s.................
`...1E17 - Le Signe.mkv', got 1671168 of 48941955 (3%) 730.4K/s ..............
`...1E17 - Le Signe.mkv', got 1900544 of 48941955 (3%) 734.7K/s .............
`...1E17 - Le Signe.mkv', got 2588672 of 48941955 (5%) 650.1K/s .............
`...1E17 - Le Signe.mkv', got 3473408 of 48941955 (7%) 727.3K/s .............
`...1E17 - Le Signe.mkv', got 4096000 of 48941955 (8%) 718.8K/s .............
`...1E17 - Le Signe.mkv', got 4816896 of 48941955 (9%) 747.9K/s .............
`...1E17 - Le Signe.mkv', got 5668864 of 48941955 (11%) 954.0K/s .............
如您所见,文件名被截断。 我的猜测是它可能是缓冲区大小问题或某些c#不喜欢的特殊字符的编码格式问题。
我还尝试通过以下命令直接将输出重定向到文件中:
ShellHelper.Bash("unbuffer lftp -p 22 -u login,password sftp://XXXXXX -e \"set mirror:use-pget-n 20; mirror --parallel=3 -c -P5 /home29/qualinost/files/tests ./tests; quit; \" > output.log");
但是还是一样,当我从c#启动时,就像bash的魅力一样,但是缺少了部分。
关于这里发生的事情有什么想法吗?
编辑:某人发表评论(并删除了它??),并指出“ c#”在输出行中给我的最大字符数为80。他要求我调整字体大小。控制台
Console.SetWindowSize(400, 800);
在我的程序开始时,它没有任何改变。但是最大80个字符可能是一个有趣的说法!
编辑2:我用sed命令清理了lftp的输出,以删除进度条,仅获取文件名及其进度。但是当我从C#启动脚本时,输出仍然被截断。 我用一个极短的文件名(yo.mkv)进行了测试,一切都在这里!所以我认为这绝对是StandardOutput的缓冲区大小问题。有没有办法定义此缓冲区的更大大小?
答案 0 :(得分:0)
我终于找到了解决此损坏的MS异步输出重定向的方法。 我使用此代码https://stackoverflow.com/a/13860551/1502444来通过在不同线程中使用StandardOutput.Read()方法并更改读取缓冲区大小来读取输出的每个字符。 感谢此解决方案和raterus的作者指出了异步读取问题。