cmd.exe process. Keep session interactive and capture through standard out - c#

I've been looking at similar posts to mine, but either my question is not answered, or I cannot understand the answer. I have used many code snippets off here to get started; so thanks for that ;-)
My requirement is to create an interactive cmd.exe window, and output results to text box ( to parse data ) eg, send command "cd /"; see the output then send command "dir" to show that I am in the new directory. Once I have this cracked, then I plan to parse the received text output and expand my application
I can currently do both things, but not at the same time.
I am new to c#, and have been stuck on this for a few days now. Code posted below.
proc1 manages to keep the session active, whereas proc2 outputs the text to a text box (I'll later on out it into a string to parse); but I can't manage to do both requirements at the same time.
I can explain more why I want to do this, but ultimately to create a concept application to expand once I have the basics cracked...
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.Diagnostics;
using System.IO;
namespace ConsoleTest_07_07_14
{
public partial class Form1 : Form
{
Process proc1 = new Process();
Process proc2 = new Process();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
SetProc1();
proc1.Start();
SetProc2();
proc2.Start();
}
public void SetProc1()
{
proc1.StartInfo.FileName = #"C:\Windows\System32\cmd.exe";
proc1.StartInfo.WorkingDirectory = #"C:\Windows";
proc1.StartInfo.UseShellExecute = false;
proc1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc2.StartInfo.CreateNoWindow = true;
proc1.StartInfo.RedirectStandardInput = true;
// proc2.StartInfo.RedirectStandardOutput = true;
}
public void SetProc2()
{
proc2.StartInfo.FileName = #"C:\Windows\System32\cmd.exe";
proc2.StartInfo.WorkingDirectory = #"C:\Windows";
proc2.StartInfo.UseShellExecute = false;
proc2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc2.StartInfo.CreateNoWindow = true;
proc2.StartInfo.RedirectStandardInput = true;
proc2.StartInfo.RedirectStandardOutput = true;
}
private void button1_Click(object sender, EventArgs e)
{
// process1
StreamWriter SW1 = proc1.StandardInput;
SW1.WriteLine(textBox3.Text);
}
private void button2_Click(object sender, EventArgs e)
{
proc2.StartInfo.Arguments = "/c dir";
proc2.Start();
StreamReader SR2 = proc2.StandardOutput;
textBox2.Text = SR2.ReadToEnd();
}
}
}

If you're just looking to build your own cmd wrapper, basically input commands into a TextBox and output them to another TextBox, this will do:
public partial class Form1 : Form
{
string OutputData;
public Form1()
{
InitializeComponent();
}
public ProcessStartInfo SetProcStartInfo(string Command)
{
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd.exe", "/c " + Command);
procStartInfo.WorkingDirectory = #"C:\Windows";
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardOutput = true;
return procStartInfo;
}
private void button1_Click(object sender, EventArgs e)
{
ProcessStartInfo procStartInfo = SetProcStartInfo(this.textBox1.Text);
using (Process proc1 = Process.Start(procStartInfo))
{
proc1.EnableRaisingEvents = true;
proc1.OutputDataReceived += OnOutputDataReceived;
proc1.BeginOutputReadLine();
}
}
void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
this.OutputData += e.Data + Environment.NewLine;
SetText(this.OutputData);
}
}
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (this.textBox2.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox2.Text = text;
}
}
}

I have managed to achieve what I wanted (Code below for reference) ( Thanks to a friend at work ;-) )
My aim was to keep a windows cmd session active, and capture any output text to a string to parse.
Eg, ssh to a linux box, run ifconfig, then parse out the interfaces available on the Linux box.
Ultimate aim is to give a software house an example of what I'd like them to expand on. I wanted Application to be written in c# as that is that foundation of the application I'd like to SW house to enhance.
Now I have the basics covered I'll look to do the ssh piece....
Thanks for all comments and replies
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.Diagnostics;
using System.IO;
namespace ConsoleTest_07_07_14
{
public partial class Form1 : Form
{
delegate void SetTextCallBack(string text);
Process proc1 = new Process();
string proc1_OutputText;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
SetProc1();
}
public void SetProc1()
{
proc1.StartInfo.FileName = #"C:\Windows\System32\cmd.exe";
proc1.StartInfo.WorkingDirectory = #"C:\Windows";
proc1.StartInfo.UseShellExecute = false;
proc1.StartInfo.CreateNoWindow = true;
proc1.StartInfo.RedirectStandardInput = true;
proc1.StartInfo.RedirectStandardError = true; //why was it false??
proc1.StartInfo.RedirectStandardOutput = true;
proc1.OutputDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
proc1.ErrorDataReceived += new DataReceivedEventHandler(MyProc1OutputHandler);
proc1.Start();
proc1.BeginOutputReadLine();
}
private void button1_Click(object sender, EventArgs e)
{
// send command to process1
clearProc1_text();
SendProcessCommand(proc1, textBox2.Text);
}
private void SendProcessCommand (Process proc, string text)
{
StreamWriter SW = proc.StandardInput;
SW.WriteLine(text);
}
private void setProc1_OutputText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallBack d = new SetTextCallBack(setProc1_OutputText);
this.Invoke(d, new object[] { text });
}
else
{
proc1_OutputText += text + Environment.NewLine;
this.textBox1.Text = proc1_OutputText;
}
}
private void clearProc1_text ()
{
clearText1();
clearProc1_OutputText();
}
private void clearText1() { textBox1.Text = ""; }
private void clearProc1_OutputText() { proc1_OutputText = ""; }
private static void MyProc1OutputHandler(object sendingProcess, DataReceivedEventArgs outline)
{
Debug.Print("Called");
if (!String.IsNullOrEmpty(outline.Data))
{ //Debug.Print(outline.Data)
Form1 f = (Form1)Form.ActiveForm;
if (f != null)
{
f.setProc1_OutputText(outline.Data);
}
}
}
}
}

Related

C# display a variable in a Textbox

i am sending Sensor information with a NUCLEOF411RE to my PC. I receive this data on the COM98 with a BaudRate of 115200. Now i want to program a Windows Application that will split my string and put it on my textboxes. until now i display the data with a Button_click event. It puts values on the Textboxes that actually are the real values. But if i move my Sensor and klick the button again there should be a lot more different values, but there are the same values on the textboxes. In addition i want to refresh the textboxes automatically and not with a button click.
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.Ports;
namespace BNO080
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
getAvailablePorts();
}
public string comport;
SerialPort serial = new SerialPort();
void getAvailablePorts()
{
String[] ports = SerialPort.GetPortNames();
comboBox1.Items.AddRange(ports);
comport = comboBox1.Text;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if(comboBox1.Text=="" || textBox6.Text=="")
{
MessageBox.Show("Please Select Port Settings");
}
else
{
serial.PortName = comboBox1.Text;
serial.BaudRate = Convert.ToInt32(textBox6.Text);
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
serial.DataBits = 8;
serial.Handshake = Handshake.None;
serial.Open();
MessageBox.Show("connected!");
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Unauthorised Access");
}
}
private void button2_Click(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
MessageBox.Show("connection closed!");
serial.Close();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
textBox5.Text = serial.ReadLine();
/*String[] Stringsizes = A.Split(new char[] {' '});
textBox1.Text = Stringsizes[0];
textBox2.Text = Stringsizes[1];
textBox3.Text = Stringsizes[2];
textBox4.Text = Stringsizes[3];*/
// textBox5.Text = A;
//Array.Clear(Stringsizes, 0, 3);
}
catch (Exception) { }
}
}
}
can someone help me?
Can you give more information why you use the Button_Click Event to read the text? Maybe it is a possible way for you to subscribe for the DataReceived-Event of the COM-port?
It would look something like this:
serial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
string receivedString = serial.ReadExisting();
//Do something here...
}
I'd do a couple things. First subscribe to the DataReceived event on the serial port. This event handler will get called when there is data available on the serial port. Then in the event handler you can read from the serial port and add it to your textbox. You can't add it directly (see the AppendText function) because the event handler is called with a different thread, only the UI thread can update UI components (or you'll get a cross-thread exception).
...
public Form1()
{
InitializeComponent();
getAvailablePorts();
// Subscribe to the DataReceived event. Our function Serial_DataReceived
// will be called whenever there's data available on the serial port.
serial.DataReceived += Serial_DataReceived;
}
// Appends the given text to the given textbox in a way that is cross-thread
// safe. This can be called by any thread, not just the UI thread.
private void AppendText(TextBox textBox, string text)
{
// If Invoke is required, i.e. we're not running on the UI thread, then
// we need to invoke it so that this function gets run again but on the UI
// thread.
if (textBox.InvokeRequired)
{
textBox.BeginInvoke(new Action(() => AppendText(textBox, text)));
}
// We're on the UI thread, we can append the new text.
else
{
textBox.Text += text;
}
}
// Gets called whenever we receive data on the serial port.
private void Serial_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string serialData = serial.ReadExisting();
AppendText(textBox5, serialData);
}
Because i want to add an rotating 3D cube i decided to switch to WPF. I heard it is much easier to implement a 3D graphic there. So i copied my code to the new WPF project. But now i got already problems to visualize my values on the Textboxes. It doesnt work. It looks like the Evenhandler did not fire an event while receiving Data from the com port.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.Drawing;
namespace cube
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
getAvailablePorts();
serial.DataReceived += Serial_DataReceived;
}
public bool button3clicked = false;
public bool button4clicked = false;
public bool button5clicked = false;
SerialPort serial = new SerialPort();
void getAvailablePorts()
{
List<string> Itemlist = new List<string>();
String[] ports = SerialPort.GetPortNames();
Itemlist.AddRange(ports);
comboBox1.ItemsSource = Itemlist;
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
if (comboBox1.Text == "" || textBox6.Text == "")
{
MessageBox.Show("Please Select Port Settings");
}
else
{
serial.PortName = comboBox1.Text;
serial.BaudRate = Convert.ToInt32(textBox6.Text);
serial.Parity = Parity.None;
serial.StopBits = StopBits.One;
serial.DataBits = 8;
serial.Handshake = Handshake.None;
serial.Open();
MessageBox.Show("connected!");
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Unauthorised Access");
}
}
private void button2_Click_1(object sender, EventArgs e)
{
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
MessageBox.Show("connection closed!");
serial.Close();
textBox1.Text = "test";
}
private void AppendText(string[] text)
{
try
{
textBox1.Text = text[0];
textBox2.Text = text[1];
textBox3.Text = text[2];
textBox4.Text = text[3];
}
catch (Exception) { }
}
private void Safe_Position1(TextBox tBr1, TextBox tBi1, TextBox tBj1, TextBox tBk1, string[] text)
{
if (button3clicked == true)
{
tBr1.Text = text[0];
tBi1.Text = text[1];
tBj1.Text = text[2];
tBk1.Text = text[3];
button3clicked = false;
}
}
private void Safe_Position2(TextBox tBr2, TextBox tBi2, TextBox tBj2, TextBox tBk2, string[] text)
{
if (button4clicked == true)
{
tBr2.Text = text[0];
tBi2.Text = text[1];
tBj2.Text = text[2];
tBk2.Text = text[3];
button4clicked = false;
}
}
private void Safe_Position3(TextBox tBr3, TextBox tBi3, TextBox tBj3, TextBox tBk3, string[] text)
{
if (button5clicked == true)
{
tBr3.Text = text[0];
tBi3.Text = text[1];
tBj3.Text = text[2];
tBk3.Text = text[3];
button5clicked = false;
}
}
private void Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string serialData = serial.ReadLine();
String[] text = serialData.Split(new char[] { ' ' });
AppendText(text);
Safe_Position1(textBox5, textBox7, textBox8, textBox9, text);
Safe_Position2(textBox10, textBox11, textBox12, textBox13, text);
Safe_Position3(textBox14, textBox15, textBox16, textBox17, text);
}
private void button3_Click(object sender, EventArgs e)
{
button3clicked = true;
}
private void button4_Click(object sender, EventArgs e)
{
button4clicked = true;
}
private void button5_Click(object sender, EventArgs e)
{
button5clicked = true;
}
}
}

Why when reporting to the backgroundworker it's never get to the progresschanged event?

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.Threading;
using System.Diagnostics;
namespace ConvertVideo
{
public partial class Form1 : Form
{
string InputFile = #"C:\temp\video\new.avi";
string OutputFile = #"C:\temp\video\new.wmv";
string cmd;
string exepath = #"E:\myffmpegstatic\ffmpeg-20151217-git-9d1fb9e-win64-static\bin\ffmpeg.exe";
FileInfo fi;
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
fi = new FileInfo(InputFile);
label2.Text = InputFile;
cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
backgroundWorker1.RunWorkerAsync();
}
private void ConvertNow(string cmd)
{
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
// use this event
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); // use this for synchronization
proc.Start();
// and start asynchronous read
proc.BeginOutputReadLine();
// wait until it's finished in your background worker thread
proc.WaitForExit();
}
catch(Exception err)
{
string myerr = err.ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ConvertNow(cmd);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBox1.Text = e.ProgressPercentage.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
What i want is to report both the progress and the data to the progresschanged event and updating the textbox1 and a progressBar(i have in the designer a progressBar1).
In the progressBar i want to report the convertion progress in percentages to 100%
Not sure how to make this reports but i'm sure it's not getting to the progresschanged event. Using a break point i see it's getting to the line:
backgroundWorker1.ReportProgress(0, e.Data);
In the deisgner in the backgroundworker properties WorkerReportsProgress is set to true.
Here you have said :
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data);
So, you're sending the string content of each line output by ffmpeg in the UserState parameter of the event and you are sending 0 in the progress percentage. But in your ProgressChanged handler you are only examining the ProgressPercentage argument - the one to which you are only sending zeroes.
textBox1.Text = e.ProgressPercentage.ToString();
So...naturally you're not going to see anything in your textbox except for a zero.
If you drop a listbox on your form and try, for example :
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
if (e.UserState != null)
{
listBox1.Items.Add(e.UserState.ToString());
}
}
You should find your listbox populates with the console output from ffmpeg as it works. If you want to extract a percentage from this you'll have to parse the output and estimate based on the frame number or time index how far along you are.
For alternative ways to get progress from ffmpeg, see perhaps :
ffmpeg Progress Bar - Encoding Percentage in PHP
The answer above in in PHP, but it should give you some better ideas.
For a full working example that demonstrates your approach is otherwise sound, this uses ipconfig (which everyone should have) and requires that Form1 have a backgroundworker with the ProgressChanged and DoWork events hooked up, as well as a listbox added to the form.
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();
}
private void GetIPInfo()
{
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "ipconfig.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += (sender, e) =>
backgroundWorker1.ReportProgress(0, e.Data);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
catch (Exception err)
{
string myerr = err.ToString();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GetIPInfo();
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
if (!(e.UserState == null))
{
listBox1.Items.Add(e.UserState.ToString());
}
}
}
}

How can i save settings of my app to a text file and read them back on load?

Read them back in app constructor and also maybe in other places in program.
I have a new form i created with some checkboxes:
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;
namespace Options
{
public partial class OptionsMenuForm : Form
{
public OptionsMenuForm()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Settings.downloadonstart = true;
}
else
{
Settings.downloadonstart = false;
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
Settings.loadonstart = true;
}
else
{
Settings.loadonstart = false;
}
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
Settings.startminimized = true;
}
else
{
Settings.startminimized = false;
}
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
if (checkBox4.Checked)
{
Settings.displaynotifications = true;
}
else
{
Settings.displaynotifications = false;
}
}
}
}
Now i want to save each time the state of one/any of the checkboxes.
I also added a class i'm using th pass the variables between the new form and form1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Options
{
class Settings
{
public static bool downloadonstart;
public static bool loadonstart;
public static bool startminimized;
public static bool displaynotifications;
}
}
Now how can i use this in form1 by saving the settings to a text file ?
For example in the text file the content will be something like:
CheckBox1 = true
CheckBox2 = false
CheckBox3 = false
CheckBox4 = true
And then if i change the state of one of them it will write it in the text file:
CheckBox1 = false
CheckBox2 = false
CheckBox3 = true
CheckBox4 = true
In form1 top i added
string settingsFile = "settings.txt";
string settingsFileDirectory = "\\settings";
StreamWriter writetosettingsfile;
Then in constructor
settingsFileDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) +
settingsFileDirectory;
if (!Directory.Exists(settingsFileDirectory))
{
Directory.CreateDirectory(settingsFileDirectory);
}
I know the app it self have a settings in the properties but i wanted to use a text file this time since i have many settings and i might have more later.
Or using the settings in the app in properties i did:
But now how do i use with it in my program to save every checkbox state in the new form and then using it in form1 ?
You can use json.net
Something like this to save the data
private void Form1_Load(object sender, EventArgs e)
{
checkBox1.CheckedChanged += checkBox_CheckedChanged;
checkBox2.CheckedChanged += checkBox_CheckedChanged;
checkBox3.CheckedChanged += checkBox_CheckedChanged;
checkBox4.CheckedChanged += checkBox_CheckedChanged;
}
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
var settings = new Settings();
settings.downloadonstart = checkBox1.Checked;
settings.loadonstart = checkBox2.Checked;
settings.startminimized = checkBox3.Checked;
settings.displaynotifications = checkBox4.Checked;
File.WriteAllText(#"c:\configfile.json", JsonConvert.SerializeObject(settings));
}
You can read the file like this
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(#"c:\configfile.json"));
Documentation:
http://www.newtonsoft.com/json/help/html/Introduction.htm
public OptionsMenuForm()
{
InitializeComponent();
//Read the settings from a file with comma delimited 1's and 0's or whatever you like
string[] values = System.IO.File.ReadAllText("c:\temp\a.txt").Split(',');
checkBox1.Checked = Convert.ToBoolean(Convert.ToInt32(values[0]));
checkBox2.Checked = Convert.ToBoolean(Convert.ToInt32(values[1]));;
//On checkbox changes save the settings
checkBox1.CheckedChanged +=SaveSettings;
checkBox2.CheckedChanged +=SaveSettings;
}
public void SaveSettings(object sender,EventArgs e)
{
StringBuilder sbValues = new StringBuilder();
int i = 0;
i = checkBox1.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
i = checkBox2.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
System.IO.File.WriteAllText("c:\temp\a.txt",sbValues.ToString());
}
It is recommended that you use XML when using the .NET framework.
public static void ConvertStringToXmlList()
{
XElement xml = new XElement
(
"Items",
(
from x in [YourList] select new XElement("Item", x)
)
);
XDocument doc = new XDocument
(
xml
);
doc.Save(Environment.CurrentDirectory + "/settings.xml");
}
var xmlReader = new XmlTextReader("settings.xml");
while (xmlReader.Read())
{
switch (reader.NodeType)
{
case [nodetype]:
// Code here
break;
}
}
Also, instead of creating the same event for all four checkbox's, just use 1.
Inside of the single event put:
ckCheckBox1.Checked = !ckCheckBox1.Checked;

How can i tell the StreamWriter when writing whats in the textBox1 to separate each string after a ,?

This is my code
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;
namespace Grads_Scripts
{
public partial class Form1 : Form
{
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;
public Form1()
{
InitializeComponent();
cmd = "set xsize 650 500";
ProcessCommands();
}
private void ProcessCommands()
{
cmdOutput = new StringBuilder("");
cmdProcess = new Process();
cmdProcess.StartInfo.FileName = exepath;
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)
{
cmdStreamWriter.WriteLine(textBox1.Text);
}
private void button2_Click(object sender, EventArgs e)
{
textBox2.Text = cmdOutput.ToString();
textBox2.AppendText(textBox1.Text);
}
private void button3_Click(object sender, EventArgs e)
{
cmdStreamWriter.Close();
cmdProcess.WaitForExit();
cmdProcess.Close();
}
private static void SortOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
cmdOutput.Append(Environment.NewLine + outLine.Data);
}
}
}
}
When i type in the textBox1 a command for example: set xsize 650 500 then click the button1 to execute the command it will do this command.
But now i want to be able to type more then one command for example in the textBox1 if i will type: set xsize 650 500,clear
And then click on button1 i want it to separate the two commands the first one is set xsize 650 500 and the second command is clear i will know it by the , that separate them
So what i want to do is here:
private void button1_Click(object sender, EventArgs e)
{
cmdStreamWriter.WriteLine(textBox1.Text);
}
I click only once and it will make the first command set xsize 650 500 and then automatic right after will do the second command clear so i will not need to type every single command and click the button and then type another command and click the button but to enter batch of commands separate by , and it will execute each command automatic one by one.
By logical like a list or queue of commands and it will execute command one by one automatic.
I would use split and then loop through each string
private void button1_Click(object sender, EventArgs e)
{
string[] cmdTextParts = textBox1.Text.Split(',');
foreach (string item in cmdTextParts)
{
cmdStreamWriter.WriteLine(item);
}
}

How to execute mysql query reading from .sql file and exporting to .csv or .err using C#?

I want to get the same result from a C# windows form button click as i get using this command:
mysql --host="example" --port="1111" --user="user" --password="pwd" --skip-column-names < report.sql > report.csv 2>report.err
So far i got this, i can enter a command (like dir of ipconfig) and get results. but when i enter a command that expects another value (like the password for mysql) the program freezes.
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace Crash_Report
{
public partial class masodik : Form
{
private static StringBuilder cmdOutput = null;
Process cmdProcess;
StreamWriter cmdStreamWriter;
public masodik()
{
InitializeComponent();
}
private static void SortOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
cmdOutput.Append(Environment.NewLine + outLine.Data);
}
}
private void exit_Click(object sender, EventArgs e)
{
cmdStreamWriter.Close();
cmdProcess.WaitForExit();
cmdProcess.Close();
Application.Exit();
}
private void Send_Click(object sender, EventArgs e)
{
cmdStreamWriter.WriteLine(textBox1.Text);
}
private void F5_Click(object sender, EventArgs e)
{
textBox2.Text = cmdOutput.ToString();
}
private void masodik_Load(object sender, EventArgs e)
{
cmdOutput = new StringBuilder("");
cmdProcess = new Process();
cmdProcess.StartInfo.FileName = "cmd.exe";
//cmdProcess.StartInfo.Arguments = #" /k";
cmdProcess.StartInfo.UseShellExecute = false;
cmdProcess.StartInfo.CreateNoWindow = true;
cmdProcess.StartInfo.RedirectStandardOutput = true;
cmdProcess.StartInfo.RedirectStandardInput = true;
// cmdProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
cmdProcess.OutputDataReceived += bejovo;
cmdProcess.Start();
cmdProcess.BeginOutputReadLine();
cmdStreamWriter = cmdProcess.StandardInput;
}
private void bejovo(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
textBox2.AppendText(e.Data);
textBox2.AppendText(Environment.NewLine);
}
}
}
}
Is there any way to do this?

Categories