在 C# 中或手动运行 cmdline 命令 - 结果不一样

Posted

技术标签:

【中文标题】在 C# 中或手动运行 cmdline 命令 - 结果不一样【英文标题】:Running a cmdline command in c# or manually - not the same result 【发布时间】:2014-07-22 11:53:39 【问题描述】:

我的问题是,从命令行手动运行命令或在 C# 中运行命令时,我不会得到相同的结果 我尝试将 .odt 文件转换为 .rst (reStructuredText),因此我得到了正确的工具,当我自己执行此操作时,它可以完美运行:只需在 cmd 中发送命令: “odt2rst.py 输入.odt 输出.rst” 但是当我从代码中尝试相同的时候,它就行不通了。有时会超时,有时会开始但没有结束。我的意思是我得到了 output.rst 的一半,只是在中间或某处切开。 我附上了我的 C# 代码,如果您发现我做错了什么,请告诉我;或者你有任何解决方案。

System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = "cmd.exe";
            startInfo.WorkingDirectory = txt_output.Text;
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardError = true;
            process.StartInfo = startInfo;
            process.Start();

        process.StandardInput.WriteLine(@"odt2rst.py input.odt uncut.rst");
        StreamReader k = new StreamReader(process.StandardOutput.BaseStream);
        StreamReader l = new StreamReader(process.StandardError.BaseStream);
        process.StandardInput.WriteLine(@"exit");
        MessageBox.Show(k.ReadToEnd());
        MessageBox.Show(l.ReadToEnd());

在消息框中,我看到它开始工作,但只是在中间关闭。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

问题正在刷新,数据实际上并未在进程之间发送。根据您是否在交互式终端上运行程序,标准输出刷新的方式会有所不同。

在这一行之后:

process.StandardInput.WriteLine(@"exit");

尝试添加这个:

process.StandardInput.Flush();

如果这还不够,那么问题出在脚本端刷新,请在 Python 脚本产生所有输出后尝试将刷新添加到您的 Python 脚本中。或者你也可以使用setvbuf。 This SO answer 对此有更多了解。


如果问题仍然存在,最好让脚本也具有非交互模式。如果其他用途需要交互操作,它也许可以通过额外的命令行开关启用。因此,脚本只会执行给定的转换并退出,而无需从标准输入中读取任何内容。这样你就不需要关心刷新或任何事情,当脚本退出时,一切都会被刷新。如果您需要进行多次转换,这有减慢速度的缺点,因为启动一个进程,尤其是像 Python 解释器这样的大东西,可能需要一些时间。

【讨论】:

感谢您的帮助,但不幸的是他们没有奏效。我希望标准输入刷新能够工作,但不知何故它没有,它只是将输出减半。另一方面,我尝试刷新我的 python 脚本(我必须承认我的 python 技能不是最好的)但它也失败了。如果python脚本有问题,我可以手动运行吗? 嗯,一种可能性是,Python 脚本(不是你写的,我接受它?)异步工作,并在处理所有数据之前遵守 exit。如果可能的话,我会让整个脚本成为非交互式的(可能带有一个额外的命令行参数),所以它只会进行一次转换并在完成后自行退出。 是的,这听起来确实是我最初的想法。但是,我用 process.WaitForExit() 破坏了代码,当我看到它不再计算时,我手动关闭了它。保持不变:(我链接你我使用的.py:github.com/jimklo/odt2rst/blob/master/odt2rst.py谢谢你的时间!编辑:我担心当我从 C# 运行它时它无法处理所有错误消息。有可能吗?我意思是在它总是停止的时候,我在手动操作时会收到某种“警告”,但它会继续前进,甚至还会转换该部分。 尝试在转换命令和退出命令之间添加一点睡眠。还要在转换命令(和睡眠)之后添加刷新。只是想看看会发生什么...... 我做了睡眠的事情(3 秒)。它在 1 秒后完成,然后再停留 2 秒,什么也不做,所以我真的认为必须有一些东西可以处理该错误,但我不知道为什么。它必须写出来然后继续。当我手动运行它时,它有什么不同?【参考方案2】:

我遇到了 Python 代码本身的问题。我从 Codeproject 得到它,它仍然处于 Beta 阶段,因此它并不完美。我仍然不知道为什么从 cmdline 或 automatized-cmdline 执行时它会有所不同,但我设法通过修改 Python 代码来修复它。不幸的是,没有一个 cmets 提供帮助,但非常感谢您抽出宝贵时间,非常感谢!

【讨论】:

以上是关于在 C# 中或手动运行 cmdline 命令 - 结果不一样的主要内容,如果未能解决你的问题,请参考以下文章

scrapy运行姿势scrapy.cmdline.execute

在 VS2010 中或通过 MsBuild 命令行编译解决方案时生成的代码不同

dpdk源码分析:cmdline中的命令添加

从 proc/pid/cmdline 解析命令行参数

如何写入/proc/cmdline中的kernel启动参数

02-scrapy的cmdline命令