这里有一个输入模拟器
Codeplex
这可能只是你的工作。
我正在编写一个示例代码,稍后将在这里发布,请记住,输入模拟器与Remus提供的链接中发现的类似。
编辑:
我发现这有一个局限性,你绝对可以摆脱典型的
System.Windows.Forms.SendKeys.Send
方法,它确实有效!
但是,这个过程必须
-
流没有重定向
-
不能是隐藏窗口(这是它将失败的地方,因为窗口的句柄不可见,无法将其置于前台使其处于活动状态!)
-
一个窗口,显示此过程的有效性!
在您的情况下,需要找到窗口,通过pinvoke“setForegroundWindow”将其设置为活动状态,然后发送序列
^{BREAK}
它会将ctrl+break信号发送到运行良好的进程(特别是如果进程是命令行程序/批处理文件)。这是一篇关于
CodeProject
这样做完全是为了反映发送键……我还没有将一些代码粘贴到其中来演示……
编辑2:
实际上,我很惊讶……正如这段代码所显示的(概念验证)…它使用的是:
-
输入模拟器(如前所述)
-
一个由按钮组成的Windows窗体,当加载该窗体时,它会自动运行该类。单击该按钮后,它会向隐藏的进程发送一个ctrl-break
-
输出流确实被重定向,并且是一个隐藏窗口。
-
奇怪的是,输出正在被捕获,但不会在调试窗口中显示结果,也就是说,它会被缓冲(我猜)直到进程终止,整个输出都会显示出来…
-
我有点作弊
FindWindow
API调用,因为我知道窗口的标题是,并且不知何故,能够将其置于前台,并使用输入模拟器将击键发送给它……或者使用传统的普通老版本
SendKeys
功能…我为什么
Thread.Sleep
是为了确保按键被发送到“活动前台窗口”的键盘队列中,尽管如此,“活动前台窗口”仍然是隐藏的。
-
我使用“netstat-e 5”命令永久循环,每隔5秒刷新一次结果,直到它收到一个“ctrl+c”来中断无限循环。
public partial class Form1 : Form
{
private TestNetStat netStat = new TestNetStat();
public Form1()
{
InitializeComponent();
using (BackgroundWorker bgWorker = new BackgroundWorker())
{
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
bgWorker.RunWorkerAsync();
}
}
void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("BGWORKER ENDED!");
}
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
netStat.Run();
}
void btnPost_Click(object sender, EventArgs e)
{
netStat.PostCtrlC();
System.Diagnostics.Debug.WriteLine(string.Format("[{0}] - {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), this.netStat.OutputData.Replace(Environment.NewLine, "")));
}
}
public class TestNetStat
{
private StringBuilder sbRedirectedOutput = new StringBuilder();
//
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
public static extern int SetForegroundWindow(IntPtr hwnd);
public string OutputData
{
get { return this.sbRedirectedOutput.ToString(); }
}
public void PostCtrlC()
{
IntPtr ptr = FindWindow(null, @"C:\Windows\System32\netstat.exe");
if (ptr != null)
{
SetForegroundWindow(ptr);
Thread.Sleep(1000);
WindowsInput.InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.CANCEL);
// SendKeys.Send("^{BREAK}");
Thread.Sleep(1000);
}
}
public void Run()
{
System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo();
ps.FileName = "netstat";
ps.ErrorDialog = false;
ps.Arguments = "-e 5";
ps.CreateNoWindow = true;
ps.UseShellExecute = false;
ps.RedirectStandardOutput = true;
ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
{
proc.StartInfo = ps;
proc.EnableRaisingEvents = true;
proc.Exited += new EventHandler(proc_Exited);
proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
}
void proc_Exited(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended");
}
void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (e.Data != null)
{
this.sbRedirectedOutput.Append(e.Data + Environment.NewLine);
System.Diagnostics.Debug.WriteLine("proc_OutputDataReceived: Data: " + e.Data);
}
}
}
别挑剔了,我知道
netStat
正在运行“backgroundworker”线程,我直接从主GUI线程调用了“postctrlc”方法……这是一种迂腐的概念验证代码,但它确实表明它需要实现“isynchronizeinvoke”以使其线程安全,而且……它确实有效。