Getting wifi Signal strength - c#

Is there a way to get wifi signal strength in C#? Currently I'm getting the same through
Process proc = new Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "netsh";
proc.StartInfo.Arguments = "wlan show interfaces";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
and then I get the wifi signal strength by reading the output. Is there a better way? Preferably using API's

Why don't you use a WMI query to get it in a clean way ?
private double RetrieveSignalString()
{
double theSignalStrength = 0;
ConnectionOptions theConnectionOptions = new ConnectionOptions();
ManagementScope theManagementScope = new ManagementScope("root\\wmi");
ObjectQuery theObjectQuery = new ObjectQuery("SELECT * FROM MSNdis_80211_ReceivedSignalStrength WHERE active=true");
ManagementObjectSearcher theQuery = new ManagementObjectSearcher(theManagementScope, theObjectQuery);
try
{
//ManagementObjectCollection theResults = theQuery.Get();
foreach(ManagementObject currentObject in theQuery.Get())
{
theSignalStrength = theSignalStrength + Convert.ToDouble(currentObject["Ndis80211ReceivedSignalStrength"]);
}
}
catch (Exception e)
{
//handle
}
return Convert.ToDouble(theSignalStrength);
}
Please see this for more info.
http://social.msdn.microsoft.com/Forums/en-US/34a66ee5-34f8-473d-b6f2-830a14e2300b/get-signal-strength-in-c

Related

Netsh Commands Cannot Display Correct the result in TextBox

class TcpIpCommands
{
public string Check()
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Windows\syswow64\netsh.exe";
p.StartInfo.Arguments = "int tcp show global";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(737);
p.Start();
p.WaitForExit();
return p.StandardOutput.ReadToEnd();
}
public string Command(string FileName, string Arguments)
{
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = FileName;
p.Arguments = Arguments;
p.UseShellExecute = false;
p.CreateNoWindow = true;
p.RedirectStandardOutput = true;
p.StandardOutputEncoding = Encoding.GetEncoding(737);
using (Process process = Process.Start(p))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return result;
}
}
}
public string Reseting()
{
Process p = new Process();
p.StartInfo.FileName = #"C:\Windows\syswow64\netsh.exe";
p.StartInfo.Arguments = #"interface tcp reset";
p.StartInfo.Verb = "runas";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(737);
p.Start();
p.WaitForExit();
return p.StandardOutput.ReadToEnd();
}
}
I have an problem with Command Method and Reseting Method. If i try to execute them I receive in RichTextBox the message
set global command failed on ipv4 the parameter is incorrect
But If i run netsh interface tcp show global or hit the Check Method they info me that the status are change.
here are the buttons
private void BtnCheck_Click(object sender, EventArgs e)
{
TcpIpCommands tic = new TcpIpCommands();
richTextBox1.Text = tic.Check();
}
private void btnChimney_Click(object sender, EventArgs e)
{
TcpIpCommands tic = new TcpIpCommands();
richTextBox1.Text = tic.Command(#"C:\Windows\system32\netsh.exe", "interface tcp set global chimney=enabled");
}
private void BtnReset_Click(object sender, EventArgs e)
{
TcpIpCommands tic = new TcpIpCommands();
richTextBox1.Text = tic.Reseting();
}
I cant understand why RichTextBox shows that message but the process execute succefully.
A note. I have try to run the commands with
StartInfo.Verb = "runas";
and both from
C:\Windows\System32\netsh.exe
and
C:\Windows\syswow64\netsh.exe
and i get the same error "set global command failed on ipv4 the parameter is incorrect" but the code execute and the parameter change.

How to read process Output Message from process within the process?

I am running an exe through commandline and getting following output.
C:\Users\sysadmin>C:\Users\sysadmin\Desktop\New_folder\Setup\PatchInstaller.exe
--mode=silent
C:\Users\sysadmin Begin Setup UI mode: Silent Error :
Another instance running, Only a single instance can be run at a time.
Exit Code: 11
i am running this through System.daignostics.process.
My issue is PatchInstaller.exe calling another process and the output of that nested process is what is visible with cmd. but the same result and exit code i am not able to get through Process object of PatchInstaller.exe.
Is there any way of getting output of process running within process?
Following is the code i have tired...
string command = #"C:\Users\sysadmin\Desktop\Setup\PatchInstaller.exe";
string result = string.Empty;
System.Diagnostics.ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command + " --mode=silent);
System.Diagnostics.Process proc = new Process();
procStartInfo.ErrorDialog = false;
procStartInfo.UseShellExecute = false;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
if (!string.IsNullOrEmpty(domain) && !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd))
{
procStartInfo.Domain = domain;
procStartInfo.UserName = user;
System.Security.SecureString ss = new System.Security.SecureString();
foreach (char c in pwd) { ss.AppendChar(c); }
procStartInfo.Password = ss;
}
proc = System.Diagnostics.Process.Start(procStartInfo);
proc.ErrorDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs errorLine)
{
if (errorLine.Data != null) result += "error:" + errorLine.Data +;
};
proc.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs outputLine)
{
if (outputLine.Data != null) result += outputLine.Data +;
};
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
Process[] pname = Process.GetProcessesByName("PatchInstaller");
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
proc.WaitForExit();
I don't know much about ProcessStartInfo but I have used Process before and the way to get the information out of the standard output is shown as below, I assume it should be a similar way just by accessing the StandardOutput
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine(command);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
var output = cmd.StandardOutput.ReadToEnd();
cmd.WaitForExit();
This code worked for me:
const int MAX_EXIT_WAIT_TIME = 3000;
// Fill needed data
string username = "";
string password = "";
string domain = "";
string appName = "";
var dir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
var appFullPath = Path.Combine(dir, appName);
ProcessStartInfo psi = new ProcessStartInfo(appFullPath);
psi.UserName = username;
var securePass = new System.Security.SecureString();
foreach (var c in password)
securePass.AppendChar(c);
psi.Password = securePass;
psi.Domain = domain;
psi.LoadUserProfile = false;
psi.WorkingDirectory = dir;
psi.Arguments = "";
psi.RedirectStandardOutput = true;
// Create Process object, but not start it!
var proc = new Process();
proc.StartInfo = psi;
StringCollection values = new StringCollection();
DataReceivedEventHandler outputDataReceived = (o, e) =>
{
lock (values)
values.Add(e.Data);
};
try
{
proc.OutputDataReceived += outputDataReceived;
// Only here we start process
if (!proc.Start())
throw new InvalidOperationException("Couldn't start app");
proc.BeginOutputReadLine();
proc.WaitForExit(MAX_EXIT_WAIT_TIME);
}
finally { proc.OutputDataReceived -= outputDataReceived; }
Console.WriteLine("Read {0} ", values.Count);
foreach (var item in values)
Console.WriteLine(" {0}", item);

C# program that ouputs lmstat on remote license server

I'm working on my first C# program. I've created a GUI where you select the network-licensed software package in a combobox, and it displays the license usage and statistics in a textbox (lmutil.exe).
Here's the problem: upon first selecting from the combobox, nothing happens, but when you select another software from the combobox list, it outputs the license stats from the previously selected software. Below is the code I have:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ComboBoxItem_Selected(object sender, RoutedEventArgs e)
{
if (ComboBox1.Text == "ComboItem1")
{
Process proc = new Process();
proc.StartInfo.FileName = "lmutil.exe";
proc.StartInfo.Arguments = "lmstat -a -c port#host";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
// start the process
proc.Start();
string s = proc.StandardOutput.ReadToEnd();
TextBox1.Text = s;
}
else
{
if (ComboBox1.Text == "ComboItem2")
{
Process proc = new Process();
proc.StartInfo.FileName = "lmutil.exe";
proc.StartInfo.Arguments = "lmstat -a -c port#host";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
// start the process
proc.Start();
string s = proc.StandardOutput.ReadToEnd();
TextBox1.Text = s;
}
else
{
if (ComboBox1.Text == "ComboItem3")
{
Process proc = new Process();
proc.StartInfo.FileName = "lmutil.exe";
proc.StartInfo.Arguments = "lmstat -a -c port#host";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
// start the process
proc.Start();
string s = proc.StandardOutput.ReadToEnd();
TextBox1.Text = s;
}
}
}
Not sure what GUI library you are using (Window is not a class I recognise, (I use WinForms)) but the following seems to work for me (with a real port and host name substituted for one of the three items (I only have one license server to test with)).
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(Object sender, EventArgs e){
switch (this.comboBox1.Text){
case "item1":
this.textBox1.Text = this.getLMStat(158, "ONE");
MessageBox.Show("DONE");
break;
case "item2":
this.textBox1.Text = this.getLMStat(158, "TWO");
MessageBox.Show("DONE");
break;
case "item3":
this.textBox1.Text = this.getLMStat(158, "THREE");
MessageBox.Show("DONE");
break;
default:
MessageBox.Show("Unsupported Value");
break;
}
}
private String getLMStat(int port, String server){
try {
Process proc = new Process();
proc.StartInfo.FileName = "lmutil.exe";
proc.StartInfo.Arguments = "lmstat -a -c " + port + "#" + server;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
// start the process
proc.Start();
return proc.StandardOutput.ReadToEnd();
}
catch (Exception){return "Do something with Exception";}
}
}
The message boxes are there so that you know when lmstat has returned, since it hangs for a little while (especially when the port and/or host is invalid).
Are you handling the correct event for the combo box selection changing?
Process.Start() starts the process but does not wait for it to finish. You can call proc.WaitForExit() immediately after string s = proc.StandardOutput.ReadToEnd();

How to run hidden R task?

I'm calling Rscript.exe from c# windows forms app, and the cmd window opens up for a few milliseconds. The python solution was easy: simply started pythonw.exe instead of python.exe
Here is the function:
private void runr()
{
orig = richTextBox1.Text;
System.IO.File.WriteAllText(#"C:\cp.R", richTextBox1.Text);
string cmd = #"C:\cp.R";
string args = #"";
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\Program Files\R\R-3.2.3\bin\Rscript.exe";
start.Arguments = string.Format("{0} {1}", cmd, args);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
StreamReader reader2 = process.StandardError;
string err = reader2.ReadToEnd();
richTextBox1.Text = result;
if (!string.IsNullOrEmpty(err))
richTextBox1.Text += "\nError:\n" + err;
}
}
}
Setting start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; does not work.
Set the ProcessStartInfo.CreateNoWindow Property to true. This prevents the system from creating a console window for the new process.

How do I use a list<string> to loop a process in cmd?

I have a netsh profiler that I want to get detailed information for each loop found.
private void wifiButton_Click(object sender, EventArgs e)
{
Process cmd = new Process();
cmd.StartInfo.FileName = "netsh.exe";
System.Threading.Thread.Sleep(50);
cmd.StartInfo.Arguments = "wlan show profiles";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.RedirectStandardError = true;
cmd.Start();
//* Read the output (or the error)
string output = cmd.StandardOutput.ReadToEnd();
textBox3.Text = output;
cmd.WaitForExit();
// output would be set by earlier code
var Output = textBox3.Text;
var regex = new Regex(#"All User Profile[\s]+: (.*)");
var resultList = new List<string>();
foreach (Match match in regex.Matches(Output))
{
resultList.Add(match.Groups[1].ToString());
}
textBox4.Text = string.Join(", ", resultList);
The code above works, below I want to take the list and run the results through CMD again to get the detailed results.
for (int i = 0; i < resultList.Count; i++)
{
Process cmd2 = new Process();
cmd.StartInfo.FileName = "netsh.exe";
System.Threading.Thread.Sleep(50);
cmd.StartInfo.Arguments = "wlan show profiles name=" resultList(0) + " key=clear";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.RedirectStandardError = true;
cmd.Start();
//* Read the output (or the error)
string output2 = cmd2.StandardOutput.ReadToEnd();
textBox5.Text = output2;
cmd.WaitForExit();
}
}
Im a good and used a 0 instead of the i placeholder. Also, mislabeled my second cmd run and forgot to update to cmd2, therefore the previous command line would overlap itself and break.
private void wifiButton_Click(object sender, EventArgs e)
{
Process cmd = new Process();
cmd.StartInfo.FileName = "netsh.exe";
System.Threading.Thread.Sleep(50);
cmd.StartInfo.Arguments = "wlan show profiles";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.RedirectStandardError = true;
cmd.Start();
//* Read the output (or the error)
string output = cmd.StandardOutput.ReadToEnd();
textBox3.Text = output;
cmd.WaitForExit();
System.Threading.Thread.Sleep(500);
// output would be set by earlier code
var Output = textBox3.Text;
var regex = new Regex(#"All User Profile[\s]+: (.*)");
var resultList = new List<string>();
foreach (Match match in regex.Matches(Output))
{
resultList.Add(match.Groups[1].ToString());
}
textBox4.Text = string.Join(", ", resultList);
System.Threading.Thread.Sleep(500);
for (int i = 0; i < resultList.Count; i++)
{
Process cmd2 = new Process();
cmd2.StartInfo.FileName = "netsh.exe";
System.Threading.Thread.Sleep(50);
cmd2.StartInfo.Arguments = "wlan show profiles name=" + resultList[i] + " key=clear";
cmd2.StartInfo.UseShellExecute = false;
cmd2.StartInfo.RedirectStandardOutput = true;
cmd2.StartInfo.RedirectStandardError = true;
cmd2.Start();
//* Read the output (or the error)
string output2 = cmd2.StandardOutput.ReadToEnd();
textBox5.Text = output2;
cmd2.WaitForExit();
}
}

Categories