I have a form with 3 controls:
A textbox for the user to enter
commands to send to a console
application,
A button to confirm the commands to
be sent and
A read-only textbox to display the
output from the application.
What I want is for the user to enter commands in the first textbox, press the button to enter and receive feedback via the second textbox.
I know how to use ProcessStartInfo.RedirectStandardOutput but, however, the app hangs when I use StandardOutput.ReadToEnd().
I had a look at the asynchronous Process.BeginOutputReadLine() but, even though my app does not hang, somehow I get no response in the textbox, it does absolutely nothing.
Here's my code:
public partial class MainForm : Form
{
private void MainForm_Load(object sender, EventArgs e)
{
InitializeInterpreter();
}
private void InitializeInterpreter()
{
InterProc.StartInfo.UseShellExecute = false;
InterProc.StartInfo.FileName = "app.exe";
InterProc.StartInfo.RedirectStandardInput = true;
InterProc.StartInfo.RedirectStandardOutput = true;
InterProc.StartInfo.RedirectStandardError = true;
InterProc.StartInfo.CreateNoWindow = true;
InterProc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);
InterProc.Start();
}
private static void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
OutputTextBox.Append(Environment.NewLine + outLine.Data);
}
}
private void Enterbutton_Click(object sender, EventArgs e)
{
InterProc.StandardInput.Write(CommandtextBox.Text);
InterProc.BeginOutputReadLine();
}
}
Is there any way I can have this run smoothly? Thanks.
If you want something interactive, I got this code to work (yours modified, details on modifications below)
private void InitializeInterpreter()
{
InterProc.StartInfo.UseShellExecute = false;
InterProc.StartInfo.FileName = "Echoer.exe";
InterProc.StartInfo.RedirectStandardInput = true;
InterProc.StartInfo.RedirectStandardOutput = true;
InterProc.StartInfo.RedirectStandardError = true;
InterProc.StartInfo.CreateNoWindow = true;
InterProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
InterProc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);
bool started = InterProc.Start();
InterProc.BeginOutputReadLine();
}
private void AppendTextInBox(TextBox box, string text)
{
if (this.InvokeRequired)
{
this.Invoke((Action<TextBox, string>)AppendTextInBox, OutputTextBox, text);
}
else
{
box.Text += text;
}
}
private void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
AppendTextInBox(OutputTextBox, outLine.Data + Environment.NewLine);
}
private void Enterbutton_Click(object sender, EventArgs e)
{
InterProc.StandardInput.WriteLine(CommandTextBox.Text);
}
So, I moved the BeginOutputReadLine to just after the process is started. That ensures it's really only called once. I also did an invoke required to clean up thread calls. Hopefully this should work for you.
The best solution I have found is:
private void Redirect(StreamReader input, TextBox output)
{
new Thread(a =>
{
var buffer = new char[1];
while (input.Read(buffer, 0, 1) > 0)
{
output.Dispatcher.Invoke(new Action(delegate
{
output.Text += new string(buffer);
}));
};
}).Start();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
process = new Process
{
StartInfo = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = "app.exe",
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
}
};
if (process.Start())
{
Redirect(process.StandardError, textBox1);
Redirect(process.StandardOutput, textBox1);
}
}
I've used code something like this:
public static void Run(string fileName, string arguments, out string standardOutput, out string standardError, out int exitCode)
{
Process fileProcess = new Process();
fileProcess.StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
};
bool started = fileProcess.Start();
if (started)
{
fileProcess.WaitForExit();
}
else
{
throw new Exception("Couldn't start");
}
standardOutput = fileProcess.StandardOutput.ReadToEnd();
standardError = fileProcess.StandardError.ReadToEnd();
exitCode = fileProcess.ExitCode;
}
But it's not interactive. But if the app is interactive, it'll take a lot more code anyway.
Where are you calling StandardOutput.ReadToEnd()? I once had a similar problem because I was calling Process.WaitForExit() before StandardOutput.ReadToEnd(). I had a large amount of input, and the output buffer was full before completion and my process was blocked.
You must call StandardOutput.ReadToEnd()before Process.WaitForExit().
Related
i'm trying to open a process with c# and react to it, when it's been closed. This work's for me:
private void StartProc()
{
var process = new System.Diagnostics.Process { StartInfo = { FileName = "PathTo.exe" } };
process.Start();
process.EnableRaisingEvents = true;
process.Exited += this.Editor_Exited;
}
private void Editor_Exited(object sender, EventArgs e)
{
MessageBox.Show("Process canceled");
}
Lets say I'm opening a text editor with this code. If there is already an instance of this text editor the code won't open a second instance and also jumps instant in the Editor_Exited Code.
I want the code to open a new instance and don't jump in the Editor_Exited code.
string processName = "PathTo.exe";
var process = new System.Diagnostics.Process { StartInfo = { FileName = processName } };
if (process.Start())
{
process.EnableRaisingEvents = true;
process.Exited += this.Editor_Exited;
}
else
{
var p = Process.GetProcessesByName(processName);
p.WaitForExit();
}
I get this is not 100% what you are asking for, but its a work around
I've been working on a project called Borealis Server Manager (https://github.com/cyberstrawberry101/Borealis-Server-Manager) since May of this year. I need help from anyone skilled enough in C# to do the following:
Allow the user to start multiple gameserver processes with arguments given to them, in upwards of dozens or hundreds of them as background processes, and still be able to switch the redirected output and input to those processes on-the-fly to the console window within Borealis.
This is what the console page looks like in Borealis:
You can see the screenshot here.
This is the code that currently launches the programs, merged with some code that was suggested by another Facepunch user months ago, but their new code seems to freeze Borealis while even one server is running, which is actually a step backwards, and I can't even get it to properly redirect console output into my console window in Borealis. I am completely okay with a rewrite of the code should someone step up to help Borealis enter beta stages. I've had the code functional enough to launch the servers externally, but internally, I can only get one server's output at a time, without killing all of the other servers. It's a pretty complex problem.
using MetroFramework;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Borealis
{
public partial class TAB_CONTROL : Form
{
#region pInvoke
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
// Enumerated type for the control messages sent to the handler routine
enum CtrlTypes : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
public static void StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(Process proc)
{
//This does not require the console window to be visible.
if (AttachConsole((uint)proc.Id))
{
//Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
//Must wait here. If we don't and re-enable Ctrl-C handling below too fast, we might terminate ourselves.
var wasAborted = false;
var procTask = Task.Run(() =>
{
//This is necessary because when we kill the process, it obviously exits. At that point, there is no proc object to wait for any longer
if (!wasAborted)
proc.WaitForExit();
});
if (!procTask.Wait(10000))
{
wasAborted = true;
proc.Kill();
}
FreeConsole();
//Re-enable Ctrl-C handling or any subsequently started programs will inherit the disabled state.
SetConsoleCtrlHandler(null, false);
}
}
#endregion
private CancellationTokenSource cancelToken;
public TAB_CONTROL()
{
InitializeComponent();
}
//===================================================================================//
// UI HANDLING CODE //
//===================================================================================//
private void ServerControl_Load(object sender, EventArgs e)
{
//Pull all gameserver data from gameservers.json, split all json strings into a list, iterate through that list for specific data.
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly);
}
}
}
private void comboboxGameserverList_SelectedValueChanged(object sender, EventArgs e)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text)
{
//Decide what data to pull from the object at this point in time of development.
GameServer_Object Controlled_GameServer = new GameServer_Object();
Controlled_GameServer.DIR_install_location = Controlled_GameServer.DIR_install_location;
Controlled_GameServer.SERVER_executable = Controlled_GameServer.SERVER_executable;
Controlled_GameServer.SERVER_launch_arguments = Controlled_GameServer.SERVER_launch_arguments;
Controlled_GameServer.SERVER_running_status = Controlled_GameServer.SERVER_running_status;
}
}
btnStartServer.Visible = true;
chkAutoRestart.Visible = true;
lblAutoRestart.Visible = true;
chkStandaloneMode.Visible = true;
lblStandaloneMode.Visible = true;
consolePanel.Visible = true;
}
private void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
consoleOutputList.Items.Add(e.Data);
}
}
private void RefreshData()
{
comboboxGameserverList.Items.Clear();
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly);
}
}
}
private void ServerControl_Activated(object sender, EventArgs e)
{
RefreshData();
}
private void chkStandaloneMode_OnValueChange(object sender, EventArgs e)
{
if (chkStandaloneMode.Value == true)
{
consolePanel.Visible = false;
}
else
{
consolePanel.Visible = true;
}
}
//===================================================================================//
// SERVER CONTROL: //
//===================================================================================//
private void LaunchServer(string SERVER_executable, string SERVER_launch_arguments, Action<string> redirectedOutputCallback = null, TextReader input = null, string argWorkingDirectory = null, EventHandler onExitedCallback = null, CancellationToken cancelToken = default(CancellationToken))
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.Arguments = SERVER_launch_arguments;
startInfo.FileName = SERVER_executable;
if (redirectedOutputCallback != null) //Redirect Output to somewhere else.
{
startInfo.UseShellExecute = false; //Redirect the programs.
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.ErrorDialog = false;
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (var process = Process.Start(startInfo))
{
if (onExitedCallback != null)
{
process.EnableRaisingEvents = true;
process.Exited += onExitedCallback;
}
if (cancelToken != null)
{
cancelToken.Register(() =>
{
StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(process);
redirectedOutputCallback?.Invoke("Shutting down the server...");
});
}
process.OutputDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args?.Data))
redirectedOutputCallback(args.Data);
};
process.BeginOutputReadLine();
process.ErrorDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args?.Data))
redirectedOutputCallback(args.Data);
};
process.BeginErrorReadLine();
//For whenever input is needed
string line;
while (input != null && (line = input.ReadLine()) != null)
process.StandardInput.WriteLine(line);
process.WaitForExit();
}
}
catch
{
StringBuilder errorDialog = new StringBuilder();
errorDialog.Append("There was an error launching the following server:\n")
.Append(startInfo.FileName)
.Append("\n\n")
.Append("[Retry]: Attempt to start the same server again.\n")
.Append("[Cancel]: Cancel attempting to start server.");
}
}
else //No not redirect output somewhere else
{
startInfo.UseShellExecute = true; //Execute the programs.
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
StringBuilder errorDialog = new StringBuilder();
errorDialog.Append("There was an error launching the following server:\n")
.Append(startInfo.FileName)
.Append("\n\n")
.Append("[Retry]: Attempt to start the same server again.\n")
.Append("[Cancel]: Cancel attempting to start server.");
}
}
}
private void btnStartServer_Click(object sender, EventArgs e)
{
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text)
{
//SOURCE ENGINE HANDLER
if (gameserver.ENGINE_type == "SOURCE")
{
//Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis.
if (chkStandaloneMode.Value == true) //To be hopefully depreciated soon. Only needed right now as a fallback option to server operators.
{
LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0} +port {1} +map {2} +maxplayers {3}",
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_map,
gameserver.GAME_maxplayers));
}
else
{
LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0} +port {1} +map {2} +maxplayers {3}",
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_map,
gameserver.GAME_maxplayers));
}
}
//SOURCE ENGINE HANDLER
if (gameserver.ENGINE_type == "UNREAL")
{
//Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis.
if (chkStandaloneMode.Value == true)
{
/*LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0}?{1}?Port={2}?MaxPlayers={3}",
gameserver.GAME_map,
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_maxplayers));
*/
}
else
{
MetroMessageBox.Show(BorealisServerManager.ActiveForm, "Unfortunately Borealis cannot directly control console output at this time; instead, please launch the server in 'standalone mode'.", "Unable to launch server within Borealis.", MessageBoxButtons.OK, MessageBoxIcon.Error);
/*
chkAutoRestart.Visible = false;
lblAutoRestart.Visible = false;
chkStandaloneMode.Visible = false;
lblStandaloneMode.Visible = false;
btnStartServer.Enabled = false;
btnStopServer.Visible = true;
consolePanel.Visible = true;
txtboxIssueCommand.Visible = true;
txtboxIssueCommand.Text = " > Enter a Command";
txtboxIssueCommand.Enabled = true;
Execute(Environment.CurrentDirectory + gameserver.SERVER_executable, gameserver.SERVER_launch_arguments, true);
*/
}
}
}
}
}
}
private void btnStopServer_Click(object sender, EventArgs e)
{
btnStopServer.Visible = false;
btnStartServer.Enabled = true;
chkAutoRestart.Visible = true;
lblAutoRestart.Visible = true;
txtboxIssueCommand.Visible = false;
consoleOutputList.Items.Clear();
txtboxIssueCommand.Text = " > Server is Not Running";
txtboxIssueCommand.Enabled = false;
cancelToken.Cancel();
backgroundWorker01.RunWorkerCompleted += (sender2, e2) =>
{
btnStopServer.Enabled = false;
btnStartServer.Enabled = true;
txtboxIssueCommand.Enabled = false;
txtboxIssueCommand.Text = "> Server is not running";
consoleOutputList.Items.Add("Server stopped...");
};
}
private void txtboxIssueCommand_Enter(object sender, EventArgs e)
{
txtboxIssueCommand.Text = "";
}
private void txtboxIssueCommand_MouseClick(object sender, MouseEventArgs e)
{
txtboxIssueCommand.Text = "";
}
private void backgroundWorker01_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
bool stopped = false;
//It's an assumption that these 3 elements MUST exist
var asyncCallback = comboboxGameserverList.BeginInvoke((Func<string[]>)delegate ()
{
return new string[] {
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "installation_folder" ),
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "default_launchscript" ),
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "binaries" )
};
});
asyncCallback.AsyncWaitHandle.WaitOne();
var serverParams = comboboxGameserverList.EndInvoke(asyncCallback) as string[];
Action<string> textAddCallback = (args) =>
{
consoleOutputList.BeginInvoke((Action)delegate ()
{
consoleOutputList.Items.Add(args);
});
};
EventHandler exitedHandler = (sender2, e2) =>
{
if (!cancelToken.IsCancellationRequested)
{
//Wait a little until we restart the server
consoleOutputList.BeginInvoke((Action)delegate ()
{
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add("An error occured and the process has crashed. Auto-restarting in 5 seconds...");
//Scroll to the bottom
consoleOutputList.TopIndex = consoleOutputList.Items.Count - 1;
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
});
Thread.Sleep(5000);
}
else
stopped = true;
};
while (chkAutoRestart.Value && !stopped)
LaunchServer(serverParams[0] + serverParams[2], serverParams[1], textAddCallback, null, serverParams[0], chkAutoRestart.Value ? exitedHandler : null, chkAutoRestart.Value ? cancelToken.Token : default(System.Threading.CancellationToken));
}
}
}
when i invoke the external exe from code and redirect output to my UI richtextbox after sometime the UI hangs and not shows the output on the screen, It slowly starts delay the output on the UI screen, any one have idea why this is happening.Here's my code
private void RunExe(string arg)
{
var cmdStartInfo = new ProcessStartInfo
{
Arguments = arg,
FileName = System.IO.Path.Combine(Application.StartupPath, #"Demo.exe"),
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
_cmd = new Process {StartInfo = cmdStartInfo};
_cmd.OutputDataReceived +=new DataReceivedEventHandler(OutputHandler);
_cmd.Start();
ProcessId = _cmd.Id;
_enableButton = new Task(_cmd_Exited);
_enableButton.Start();
MyTabControl.Visibility = Visibility.Visible;
if (!MyTabControl.Items.Contains(ConsoleTabItem))
{
MyTabControl.Items.Add(ConsoleTabItem);
}
txtConsoleOutput.Document.Blocks.Clear();
ConsoleTabItem.Focus();
ConsoleTabItem.Visibility = Visibility.Visible;
ConsoleTabItem.IsEnabled = false;
_cmd.BeginOutputReadLine();
LoadResults();
}
And for the output handler
private void OutputHandler(object sender, DataReceivedEventArgs e)
{
try
{
if (e.Data != null)
{
string line;
Dispatcher.Invoke(() =>
{
line = e.Data;
if (line != null)
{
txtConsoleOutput.AppendText(line + "\n");
ConsoleScrollerView.ScrollToBottom();
}
});
}
}
catch (NullReferenceException ex)
{
Console.WriteLine(ex);
}
}
I'll really appreciate for any help ..Thanks
I have been working on a manager application for a Minecraft server, when I run my program, the console shows and disappears, if I run it manually, it runs without and problems. My code:
Process process = new Process
{
StartInfo =
{
FileName = textBox2.Text,
//Arguments = textBox3.Text,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
}
};
process.OutputDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
server = process;
process.Start();
Batch file code (idk what language are batch files, so I used default one - Select Language):
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
BTW. Can you start processes without creating files ? (ex. Start process "java -jar example", without creating file) ?
#Edit Answer to the third question: Answer to the third question
My full code (MessageBoxes are in Polish, becouse im from Poland, but later i will add support for other languages):
using System;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Process server;
private Boolean runServer()
{
if (!File.Exists(textBox2.Text))
{
MessageBox.Show("Brak określonej ścieżki dostępu! (" + textBox2.Text + ")", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
Process process = new Process
{
StartInfo =
{
FileName = textBox2.Text,
//Arguments = textBox3.Text,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
}
};
process.OutputDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(server_outputDataReceived);
server = process;
if (process.Start())
return true;
else
{
MessageBox.Show("Nie można włączyć serwera!", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
private String ReadFile(String filename, int line)
{
StreamReader reader = new StreamReader(filename);
for (int i = 0; i < line; i++)
{
reader.ReadLine();
}
return reader.ReadLine();
}
private void ReloadOPs()
{
if (!File.Exists(textBox1.Text))
{
MessageBox.Show("Sciezka dostępu do pliku z listą graczy posiadających OP nie istnieje! (" + textBox1.Text + ")", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
tabControl1.SelectedTab = tabPageOptions;
textBox1.SelectAll();
return;
}
String line = ReadFile(textBox1.Text, 0);
comboBox1.Items.Clear();
for (int i = 1; i < File.ReadAllLines(textBox1.Text).Length; i++)
{
if (!String.IsNullOrWhiteSpace(ReadFile(textBox1.Text, i)))
{
comboBox1.Items.Add(line);
line = ReadFile(textBox1.Text, i);
}
}
MessageBox.Show("Lista graczy z OP, została odświeżona.");
}
// OPs combobox (OPs)
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
groupBox1.Text = comboBox1.SelectedItem.ToString();
groupBox1.Visible = true;
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = Application.StartupPath.ToString() + #"\ops.txt";
ReloadOPs();
}
// Reload OPs button (OPs)
private void button1_Click(object sender, EventArgs e)
{
ReloadOPs();
}
// Save button (Options)
private void button4_Click(object sender, EventArgs e)
{
}
private void server_outputDataReceived(object sender, DataReceivedEventArgs e)
{
addConsoleMessage(e.Data.ToString(), true);
}
// Run server button (Menu)
private void button5_Click(object sender, EventArgs e)
{
if (!runServer())
return;
server.BeginOutputReadLine();
button6.Enabled = true;
}
// Stop server button (Menu)
private void button6_Click(object sender, EventArgs e)
{
if(!server.HasExited)
server.Kill();
button6.Enabled = false;
}
private void addConsoleMessage(String message, Boolean refresh)
{
listBox1.Items.Add(message);
if (refresh)
listBox1.Refresh();
}
}
}
Works now, but after second message that batch file returned (?), program crashes becouse InvaildOperationException was unhandled.
Ok. Let's clarify some points. I assume you have a Batch file named filename.bat with this content:
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
and with "run it manually" you mean you open a command-line window and enter: filename. Ok? However, you have NOT indicated how do you run your Batch file when NOT run it manually! If you double-click on it from the file browser, then your Batch file missing to change current directory to the one where the Batch file is:
cd "%~P0"
java -Xmx1024M -jar craftbukkit-1.7.2-R0.3.jar -o false
PS - Your Batch file should NOT be named start.bat because start is the name of an internal cmd.exe command!
Hi I want to start a single cmd process from which i can read and write from my windows application form. I want to highlight that i dont want to keep on create a new cmd process for each command that i enter. My code is a mess now. . .
I have a windows form application now with just 2 textboxes and a button.
Textbox1 is for the output.
Textbox2 in for the input.
Button is to send the input.
Process cmd = new Process();
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = "cmd.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardInput = true
};
StreamReader sr;
StreamWriter sw;
private void Form1_Load(object sender, EventArgs e)
{
cmd.StartInfo = psi;
cmd.Start();
sr = cmd.StandardOutput;
sw = cmd.StandardInput;
sw.AutoFlush = true;
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(GetOutput));
t.Start();
}
delegate void Write(string Text);
private void SetTextBox(string Text)
{
if (textBox1.InvokeRequired)
{
textBox1.Invoke(new Write(SetTextBox),Text);
}
else
textBox1.Text += Text;
}
private void GetOutput()
{
while (true)
{
if (sr.Peek() != -1)
SetTextBox(sr.ReadToEnd());
else
System.Threading.Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
sw.WriteLine(textBox2.Text);
textBox2.Clear();
}
Try using the /k argument, which tells CMD.exe to open, run the specified command, then keep the window open.