如何捕获第二个控制台窗口显示外部进程并将其添加到winform上的pictureBox?

时间:2015-12-30 16:34:07

标签: c# .net winforms

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Drawing.Imaging;

namespace Grads_Scripts
{
    public partial class Form1 : Form
    {
        // ****************** \\

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        public static extern long SetWindowPos(IntPtr hwnd, IntPtr hWndInsertAfter, long x, long y, long cx, long cy,
                                               long wFlags);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

        [DllImport("kernel32.dll")]
        static extern bool CreateProcess(string lpApplicationName,
                                           string lpCommandLine,
                                           IntPtr lpProcessAttributes,
                                           IntPtr lpThreadAttributes,
                                           bool bInheritHandles,
                                           uint dwCreationFlags,
                                           IntPtr lpEnvironment,
                                           string lpCurrentDirectory,
                                           ref STARTUPINFO lpStartupInfo,
                                           out PROCESS_INFORMATION lpProcessInformation);

        public const int WM_SYSCOMMAND = 0x112;
        public const int SC_MINIMIZE = 0xf020;
        public const int SC_MAXIMIZE = 0xf030;


        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }

        public struct STARTUPINFO
        {
            public uint cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        public struct SECURITY_ATTRIBUTES
        {
            public int length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        string cmd = "";
        string exepath = @"C:\OpenGrADS\Contents\Cygwin\Versions\2.0.2.oga.2\i686\opengrads.exe";
        private static StringBuilder cmdOutput = null;
        Process cmdProcess;
        StreamWriter cmdStreamWriter;
        string pathDir = Path.GetDirectoryName(Application.LocalUserAppDataPath) + "\\settings";
        string settingsFile = "settings.txt";
        StreamWriter w;

        public Form1()
        {
            InitializeComponent();

            button4.Enabled = false;
            textBox1.Enabled = false;
            button1.Enabled = false;
            button2.Enabled = false;
            if (!Directory.Exists(pathDir))
                Directory.CreateDirectory(pathDir);
            settingsFile = Path.Combine(pathDir, settingsFile);
            if (File.Exists(settingsFile))
                textBox1.Text = File.ReadAllText(settingsFile);
            button1.Select();
            textBox2.Text = Properties.Settings.Default.MySettings;
            if (textBox2.Text != "" && File.Exists(textBox2.Text))
            {
                button4.Enabled = true;
                textBox1.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;
                ProcessCommands();
            }
            if (File.Exists(exepath) && textBox2.Text == "")
            {
                textBox2.Text = exepath;
                button4.Enabled = true;
                textBox1.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;
                Properties.Settings.Default.MySettings = textBox2.Text;
                Properties.Settings.Default.Save();
                ProcessCommands();
            }
            else
            {
                button4.Enabled = true;
            }
        }

        private void ProcessCommands()
        {
            cmdOutput = new StringBuilder("");
            cmdProcess = new Process();

            cmdProcess.StartInfo.FileName = textBox2.Text;
            cmdProcess.StartInfo.UseShellExecute = false;
            cmdProcess.StartInfo.CreateNoWindow = true;
            cmdProcess.StartInfo.RedirectStandardOutput = true;

            cmdProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
            cmdProcess.StartInfo.RedirectStandardInput = true;
            cmdProcess.Start();

            cmdStreamWriter = cmdProcess.StandardInput;
            cmdProcess.BeginOutputReadLine();

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            string[] cmdTextParts = textBox1.Text.Split(',');
            foreach (string item in cmdTextParts)
            {
                cmdStreamWriter.WriteLine(item);
            }

            System.Threading.Thread.Sleep(10000);
            Process[] processlist = Process.GetProcesses();
            List<string> names = new List<string>();
            foreach (Process process in processlist)
            {
                if (!String.IsNullOrEmpty(process.MainWindowTitle))
                {
                    if (process.MainWindowTitle.Contains("GrAD"))
                    {
                        names.Add(process.ProcessName + " " + process.Id + " " + process.MainWindowTitle);
                        if (process.ProcessName == "Xming")
                        {
                            CaptureApplication(process.MainWindowTitle);
                            break;
                        }
                    }
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string result = Regex.Replace(cmdOutput.ToString(), @"\e\[(\d+;)*(\d+)?[ABCDHJKfmsu]", "");
            richTextBox1.Text = result;//cmdOutput.ToString();
            richTextBox1.AppendText(textBox1.Text);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            cmdStreamWriter.Close();
            cmdProcess.WaitForExit();
            cmdProcess.Close();
        }

        private void SortOutputHandler(object sendingProcess,
            DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                cmdOutput.Append(Environment.NewLine + outLine.Data);
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            w = new StreamWriter(settingsFile, false);
            w.Write(textBox1.Text);
            w.Close();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog theDialog = new OpenFileDialog();
            theDialog.Title = "Open Grads File";
            theDialog.Filter = "EXE files|opengrads.exe";
            theDialog.InitialDirectory = @"C:\";
            if (theDialog.ShowDialog() == DialogResult.OK)
            {
                textBox2.Text = theDialog.FileName;
                button4.Enabled = true;
                textBox1.Enabled = true;
                button1.Enabled = true;
                button2.Enabled = true;
                Properties.Settings.Default.MySettings = textBox2.Text;
                Properties.Settings.Default.Save();
                ProcessCommands();
            }
        }

        public void CaptureApplication(string _title)
        {
            string _wndcls = "ConsoleWindowClass";
            STARTUPINFO si = new STARTUPINFO();
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            CreateProcess(_title, null, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si, out pi);
            IntPtr _wndConsole = IntPtr.Zero;
            for (int i = 0; i < 30; i++)
            {
                _wndConsole = FindWindow(_wndcls, _title);
                if (_wndConsole == IntPtr.Zero)
                {
                    System.Threading.Thread.Sleep(10);
                    continue;
                }
                break;

            }    
                IntPtr value = SetParent(_wndConsole, this.pictureBox1.Handle);
                int style = GetWindowLong(_wndConsole, -16);
                style &= -12582913;
                SetWindowLong(_wndConsole, -16, style);
                SendMessage(_wndConsole, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
        }
    }
}

当我单击button1时,单击事件,程序将命令发送到我在exepath变量中运行的opengrads.exe的控制台窗口。 命令运行后,opengrads.exe打开一个名为Xming的新进程。 我可以在托盘图标这个Xming开始运行。所以首先我opengrads.exe然后它让Xming开始跑步。

现在,如果在方法CaptureApplication作为标题,我将放入button1点击事件opengrads.exe,它将捕获opengrads.exe控制台窗口并将其添加到我的{{1 }} form1

我想抓住Xming控制台窗口并将其添加到pictureBox1

pictureBox1点击后,我进行了测试,可以找到Xming流程并获取其身份名称button1尝试发送给mainwindowtitle&#34; Xming&#34 ;然后&#34; Xming.exe&#34;没有工作尝试发送到CaptureApplication的方法,但也没有工作。

这是我右边的程序的屏幕截图,你可以看到左边MainWindowTitle中捕获的opengrads.exe是我要捕获的Xming窗口,但是可以&#t; tt:

My program screenshot

在我要添加到pictureBox1的左侧窗口中。我看到它的标题pictureBox1试图将其作为标题发送到GrADS 2.0.2.oga.2方法,但它也没有用。

如果有帮助,您可以下载CaptureApplication here

1 个答案:

答案 0 :(得分:0)

您可以重定向流程&#39; stardard输出流并捕获它输出到字符串的任何内容。

Process proc = new Process();
proc.StartInfo.FileName = "myapp.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();    

Console.WriteLine(proc.StandardOutput.ReadToEnd());

proc.WaitForExit();

然后,您可以通过标准Graphics调用将捕获的字符串绘制到您的位图。