How to publish messages to MQTT with mosquitto_pub in .net - c#

I am using this link => How to test the `Mosquitto` server? . for communicating data between two command prompt. it is worked perfectly.
Now I am using windows application for communication between device and server. i am using the reference https://gist.github.com/cwschroeder/7b5117dca561c01def041e7d4c6d2771
I am using the code in command prompt for subscribe is given below
mosquitto_sub -v -t 'test/topic'
Iam using the following code to publish(mqtt)
public Form1()
{
InitializeComponent();
// string BrokerAddress = "test.mosquitto.org";
string BrokerAddress = "localhost";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
}
private void btnPublish_Click(object sender, EventArgs e)
{
if (txtTopicPublish.Text != "")
{
// whole topic
string Topic = "/ElektorMyJourneyIoT/" + txtTopicPublish.Text + "/test";
MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, true);
// publish a message with QoS 2
client.Publish(Topic, Encoding.UTF8.GetBytes(txtPublish.Text), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, true);
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine("mosquitto_pub -t 'test/topic' -m 'xyz' ");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
//cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
//Console.ReadKey();
}
else
{
MessageBox.Show("You have to enter a topic to publish!");
}
}
From the above code, you can see manually written commands for passing commands to command prompt. which is cmd.StandardInput.WriteLine("mosquitto_pub -t 'test/topic' -m 'xyz' ");
I need to publish message without manual code. need to write publish through .net.

Related

How to run deepfreeze command line using command prompt in c#

i am working with services using C#, and for some stuff i need to get deepfreeze state of the station (frozen or thawed), for this found this on Faronic's documentation , when i use the following command in command prompt : C:\WINDOWS\syswow64\DFC.exe get /ISFROZEN it works and returns "THAWED." or "FROZEN." so i decided in my C# program to run a command prompt and redirect the Standard output to get the result of the command into a string variable , but it has not worked, i tried with any other commands and it works , i do not understand where is the problem.
there is the DFC.exe download link if it does not exists ( complete the captcha and click to download)
It is my third day on it so i need help .. thank's for everyone , there is sample code :
string pathDf = #"C:\WINDOWS\syswow64\DFC.exe";
string cmdline = string.Format("{0} get /ISFROZEN ", pathDf);
string msg = "";
if (File.Exists(pathDf))
{
Process cmd = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "cmd.exe";
startInfo.CreateNoWindow = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
cmd.StartInfo = startInfo;
cmd.Start();
cmd.StandardInput.WriteLine(cmdline);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
Console.ReadKey();
}
the command still not works .. but i found another way to get deepfreeze state , using registry key
private static string GetDeepFreezeState()
{
string result = "";
try
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\WOW6432Node\Faronics\Deep Freeze 6");
if (key != null)
{
Object o = key.GetValue("DF Status");
if (o != null)
{
result = o.ToString();
}
}
}
catch (Exception ex)
{
//react appropriately
FilesUtilities.WriteLog(ex.Message,FilesUtilities.ErrorType.Error);
}
return result;
}
Maybe it will help someone.
On the other hand i still not able to run deepfreeze command line on my C# program, if someone has an answer , please help...
Another way to get Deepfreeze state using registry key
$path = 'HKLM:\SOFTWARE\WOW6432Node\Faronics\Deep Freeze 6'
$Key = 'DF Status'
$State = Get-ItemPropertyValue -path $path -name $Key -ErrorAction SilentlyContinue
if ($State='Frozen') {Echo "Deepfreeze is currently Frozen"} else {Echo "Deepfreeze is currently UN-Frozen"}
pause

How to stop logcat from logging and close adb programmatically?

I am writing a small C# application to collect logcat files for an app that's running on an Android device connected to the computer.
I can easily start logcat and get it to log the desired lines to a particular text file. But every command that I've tried to stop logcat from logging doesn't work.
I've tried my solutions also when running my app with admin rights.
Here is my code:
static void Main(string[] args)
{
string choice;
string clearLogging = #"adb logcat -c";
string startLogging = #"adb logcat MyApp_LoggingTag:V AndroidRuntime:E *:S > C:\logcat.txt";
string adbDir = #"C:\Users\me\AppData\Local\Android\android-sdk\platform-tools\";
string clearCommand = adbDir + clearLogging;
string startLoggingCommand = adbDir + startLogging;
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe", "/K " + clearCommand);
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
//Tried giving the cmd process elevated rights and then use logcat -c - didn't work
//startInfo.Verb = "runas";
Process logcatRunner = Process.Start(startInfo);
//This works!
logcatRunner.StandardInput.WriteLine(startLoggingCommand);
Console.WriteLine("Logging has started.");
Console.Write("Press Enter to stop logging....");
Console.ReadLine();
//-c doesn't work
//logcatRunner.StandardInput.WriteLine(clearCommand);
//Tried killing adb via the logcatRunner process - doesn't work.
//logcatRunner.StandardInput.WriteLine(#"taskkill -f /im ""adb.exe""");
//Tried killing my process - doesn't work - adb is still running and logcat is still writing logs
//logcatRunner.Kill();
Console.WriteLine("Logging has stopped.");
Console.Write(#"Enter any key");
choice = Console.ReadLine();
}
adb is still running after I close the above application.
So my question is, having started adb and logcat successfully, how do I close both of them programmatically?
Doing this with your approach is complicated. You create cmd process and then start another process (adb) there. To kill adb you need to send CTRL+C to cmd, but it's not that easy because of CreateNoWindow=true. I'd suggest another approach and run adb directly, redirecting its output:
string adbPath = #"G:\Android\android-sdk\platform-tools\adb.exe";
ProcessStartInfo startInfo = new ProcessStartInfo(adbPath, "logcat MyApp_LoggingTag:V AndroidRuntime:E *:S");
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
// if you don't want to recreate it each time - choose another file mode, like FileMode.Append
using (var fs = new FileStream(#"C:\logcat.txt", FileMode.Create, FileAccess.Write, FileShare.Read)) {
using (var writer = new StreamWriter(fs)) {
Process logcatRunner = new Process();
logcatRunner.StartInfo = startInfo;
logcatRunner.EnableRaisingEvents = true;
logcatRunner.OutputDataReceived += (sender, args) => {
// Data null indicates end of output stream - don't write it
if (args.Data != null) {
writer.Write(args.Data);
// flush immediately if needed
writer.Flush();
}
};
logcatRunner.Start();
logcatRunner.BeginOutputReadLine();
Console.WriteLine("Logging started, press any key to stop");
Console.ReadKey();
logcatRunner.CancelOutputRead();
logcatRunner.Kill();
logcatRunner.WaitForExit();
}
}

C# Iperf Server

I'm trying to write a C# wrapper for Iperf server. After Iperf client is done with packet sending, the C# server application should dump the output data to the text file.
The problem is that this process (server) never exits, so it doesn't dump any data to the txt file. However, when I manually close the cmd window that runs iperf server, the text file is written with data (process exits). But this is clearly not the solution I'm looking for.
Any suggestions how can I write the data directly into the file, w/o need of manually closing the iperf server cmd window?
This is my code:
private void button1_Click(object sender, EventArgs e)
{
string commandline_server = " -s -u -i 1";
try
{
process = new Process();
process.StartInfo.FileName = "iperf.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
//process.StartInfo.RedirectStandardError = true;
process.StartInfo.Arguments = commandline_server;
process.StartInfo.CreateNoWindow = false;
process.EnableRaisingEvents = true;
process.Exited += new EventHandler(process_Exited);
process.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
void process_Exited(object sender, EventArgs e)
{
//throw new NotImplementedException();
string outfile = process.StandardOutput.ReadToEnd();
System.IO.File.WriteAllText("test.txt", outfile);
}
Instead of shelling out to a terminal, have you considered using their API? iperf3 introduced "libiperf".
There are example C-programs in their source code tree.

How to continuously output console application to text file in C#

I am trying to open up a hidden console application with arguments, and basically log it's output into a file continuously until it is stopped.
I have tried using a memory stream and writing it into the file, and it did seem to work for a bit. Now I am trying to take advantage of the DataRecievedEvent so I can further process the output. Right now I am not getting any output.
Here is how I am opening the console application:
StreamWriter writer = new StreamWriter("tsharkfieldoutput.txt", true)
private void capturePackets(int device)
{
string path =
string.Format("-i " + device +
" -O SNMP -T fields -e snmp.value.oid -e snmp.VarBind -e snmp.variable_bindings -e snmp.value.octets -e snmp.name -R udp src " +
destPort);
string tshark = #"C:\Program Files\Wireshark\tshark.exe";
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = tshark;
ps.CreateNoWindow = true;
ps.WindowStyle = ProcessWindowStyle.Hidden;
ps.UseShellExecute = false;
ps.CreateNoWindow = true;
ps.RedirectStandardOutput = true;
ps.Arguments = path;
Process process = new Process();
process.StartInfo = ps;
process.Start();
process.OutputDataReceived += new DataReceivedEventHandler(tshark_OutputDataReceived);
//Not using stream reader any more.
//StreamReader myStreamReader = process.StandardOutput;
writer.Write("Begin tshark output- " + DateTime.Now + " - " + Environment.NewLine);
}
private void tshark_OutputDataReceived(object sender, DataReceivedEventArgs arg)
{
string tsharkline = arg.Data; //arg.Data contains the output data from the process...
writer.Write(tsharkline);
}
I think the issue is that your reference to the process is going out of scope at the end of function capturePackets. You will either need to give the process variable the same scope as the writer or wait in the capturePackets function until the process exits using the WaitForExit() method. Although the process that you create continues to run, when the reference to it goes out of scope (via the process variable), the events will stop being processed.

Redirecting console output to a log file

I am working with the WMI API for c# in order to connect to a remote server and execute some commands. I have successfully established a connection. All I need now is to redirect the output of the remote CMD into a log file in my local machine.
Here is my code :
ConnectionOptions options = new ConnectionOptions();
options.Username = "login";
options.Password = "password";
ManagementScope scope = new ManagementScope("\\\\myserver\\root\\cimv2", options);
scope.Options.EnablePrivileges = true;
scope.Options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
try
{
scope.Connect();
System.Management.ManagementClass local_ClassInstance = new System.Management.ManagementClass(scope, new System.Management.ManagementPath("Win32_Process"), null);
Console.WriteLine("SUCCESS");
//execute the command
System.Management.ManagementBaseObject local_InParams = local_ClassInstance.GetMethodParameters("Create");
local_InParams["CommandLine"] = #"cmd.exe /C myCommand";
local_InParams["CurrentDirectory"] = #"mypath";
System.Management.ManagementBaseObject local_ManagementBaseObject = local_ClassInstance.InvokeMethod("Create", local_InParams, null);
}
catch (Exception e)
{
Console.WriteLine("FAILURE"+e.ToString());
}
Edit
I tried to accomplish this by using the '>' primitive :
local_InParams["CommandLine"] = "command > log.txt";
But the output file that I created doesn't contain anything.
I tried also to do this using a process
Process myProcess = new Process();
myProcess.StartInfo.FileName = "ipconfig";
myProcess.StartInfo.Arguments = "/all";
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.Start();
myProcess.WaitForExit();
string myResult = myProcess.StandardOutput.ReadToEnd();
Console.WriteLine(myResult);
myProcess.Close();
But the process does not return the information that I want because I want the output of cmd of the remote machine (Because I want the log of the behaviour of the server while running the command).
Any Help please ?
I too had an issue with capturing, and found ANOTHER redirect that works similar to what you have...
myProcess.StartInfo.RedirectStandardError = true;
// trap normal data received AND any ERROR data received too
myProcess.OutputDataReceived += DOSOutputResultsHandler;
myProcess.ErrorDataReceived += DOSOutputErrorsHandler;
I also have two string builder properties for capturing the output responses on my class that does the DOS Call process
StringBuilder DOSOutputResults = new StringBuilder();
StringBuilder DOSOutputErrors = new StringBuilder();
protected void DOSOutputResultsHandler(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data))
// track data into the NORMAL output string builder
DOSOutputResults.Append(Environment.NewLine + outLine.Data);
}
protected void DOSOutputErrorsHandler(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
// track data into the ERROR output string builder
DOSOutputErrors.Append(Environment.NewLine + outLine.Data);
}
Additionally, for using the primitive ">" redirection, there is also a "2>" redirection that handles errors not redirected to normal output. I found this out when dealing with DOS calls to Java.

Categories