好的,这就是我正在做的事情——我想编写一个将标准输出/输入重定向到富文本框的 .net 应用程序。我已经让它工作得很好,但是一旦我将标准输入添加到混合中,我的读取命令就会卡住。这是我表单中的相关代码。
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
//Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.ErrorDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.Start();
Timer consoleReader = new Timer();
consoleReader.Interval = 200;
consoleReader.Tick += new EventHandler(consoleReader_Tick);
consoleReader.Start();
}
void consoleReader_Tick(object sender, EventArgs e)
{
textArea.AppendText(Shell.StandardOutput.ReadToEnd());
}
我也尝试过使用 Process 类中可用的异步读取方法来执行此操作,但同样,一旦我将 standardinputredirect = true 添加到组合中,它可能会在读取大约一行后挂断。
有什么想法吗?
[[编辑]] 好的,这是一个示例程序。我将此代码移至控制台应用程序中以简化操作。为什么这个坏了?
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace TestAsConsoleApp
{
class Program
{
static Process Shell;
static void Main(string[] args)
{
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.Start();
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.BeginOutputReadLine();
Shell.WaitForExit();
}
static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
Console.WriteLine(e.Data);
}
}
}
最佳答案
修改后的程序看起来没有问题。您创建一个流程请求重定向所有流。您触发对创建的流程输出的异步读取。那你就等着吧。在您的情况下,创建的 cmd.exe 在其输入流中没有获得任何内容,因此它不会产生任何输出。可以试试下面的程序。运行它并给出一些命令,如 dir 等,它将产生输出。希望我没有误解你的问题。
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace TestAsConsoleApp
{
class Program
{
static Process Shell;
static void Main(string[] args)
{
Shell = new Process();
Shell.StartInfo.FileName = "cmd";
Shell.StartInfo.UseShellExecute = false;
Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Shell.StartInfo.CreateNoWindow = true;
Shell.StartInfo.RedirectStandardInput = true;
Shell.StartInfo.RedirectStandardOutput = true;
Shell.StartInfo.RedirectStandardError = true;
Shell.Start();
//Shell.StandardInput.WriteLine("dir");
Shell.EnableRaisingEvents = true;
Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
Shell.BeginOutputReadLine();
//read input from your programs input and forward that to the created cmd 's input
do
{
string aLine = Console.ReadLine();
Shell.StandardInput.WriteLine(aLine);
if (aLine.ToLower() == "exit")
break;
}while(true);
Shell.WaitForExit();
}
static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
Console.WriteLine(e.Data);
}
}
}
关于c# - 我正在为 cmd 编写包装器,但在重定向标准输入时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3486508/
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])
我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona