i'm currently writing a C# program which has similar features as wireshack, using the SharpPcap to capture the packets and PacketDotNet to get the information about the packet. I would like to know how can i get the name of the process associated with the packet??
You can get ProcessId by parsing the output from netstat -o and then get process name from Process.GetById.
May be this code will be helpful, but i'm not very strong with regexps :)
var proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "netstat",
Arguments = "-on",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
Regex r = new Regex(#"\S+\s+(?<address>\S+)\s+\S+\s+\S+\s+(?<pid>\d+)");
while (!proc.StandardOutput.EndOfStream) {
var res = r.Match(proc.StandardOutput.ReadLine());
if (res.Success) {
var pid = int.Parse(res.Groups["pid"].Value);
var address = res.Groups["address"].Value;
Console.WriteLine("{0} - {1}", address, Process.GetProcessById(pid).ProcessName);
}
}
Related
I'm running .NET Core app on the linux docker container
When I call the command from the linux terminal it works well:
./darknet detector test -out result.json < data/file-list.txt
But when I start the process from the .NET Core I see error. Process runner method:
public static string RunCommand(string command, string args)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = command,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
process.WaitForExit();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
return #$"{output}{Environment.NewLine}-------------------------------{Environment.NewLine}{error}";
}
Calling code:
string args = #$"detector test -out result.json < data/file-list.txt";
string output = ProcessRunner.RunCommand("./darknet", args);
Here is the part of the output:
Cannot load image "<"
STB Reason: can't fopen
How to fix it?
You can write the process's standard input once you set the RedirectStandartInput to true while starting your process. Here is an example how to write :
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "./ConsoleApp1.exe",
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true, // here you need
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
using var file = File.OpenRead("./1.txt");
using var reader = new StreamReader(file);
while (true)
{
var line = await reader.ReadLineAsync();
if (string.IsNullOrWhiteSpace(line)) break; // you can use some other stoping decision
await process.StandardInput.WriteLineAsync(line);
}
I have a console application and a method that executes a PowerShell script within the console application. So I'm trying to grab an error text that it outputs in the application and do something with it.
Example/What I'm trying to do:
If Error.contains("Object")
{
// do something here
}
Here is my current method
public void ExecutePowershellScript()
{
var file = #"C:\Path\filename.ps1";
var start = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = $"-NoProfile -ExecutionPolicy unrestricted -file \"{file}\"",
UseShellExecute = false
};
Process.Start(start);
}
Process.start: how to get the output?
When you create your Process object set StartInfo appropriately:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "program.exe",
Arguments = "command line arguments to your executable",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
then start the process and read from it:
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
// do something with line
}
You can use int.Parse() or int.TryParse() to convert the strings to numeric values. You may have to do some string manipulation first if there are invalid numeric characters in the strings you read.
You can set RedirectStandardError = true and access any errors from process.StandardError
public static void ExecutePowershellScript()
{
var file = #"C:\Path\filename.ps1";
var start = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = $"-NoProfile -ExecutionPolicy unrestricted -file \"{file}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using Process process = Process.Start(start);
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();
}
Okay, scratch the above suggestion.
After being corrected by mklement0,
This is a perfectly reasonable attempt, but, unfortunately, it can lead to hangs (while waiting for one's stream end, the other, when exceeding the buffer size, may cause process execution to block). If you need to capture both streams, you must collect the output from one of them via events. – mklement0
I changed the solution to use the ErrorDataReceived event
public static async Task ExecutePowershellScript()
{
var file = #"C:\Path\filename.ps1";
var start = new ProcessStartInfo
{
FileName = "powershell.exe",
Arguments = $"-NoProfile -ExecutionPolicy unrestricted -file \"{file}\"",
UseShellExecute = false,
// redirect standard error stream to process.StandardError
RedirectStandardError = true
};
using var process = new Process
{
StartInfo = start
};
// Subscribe to ErrorDataReceived event
process.ErrorDataReceived += (sender, e) =>
{
// code to process the error lines in e.Data
};
process.Start();
// Necessary to start redirecting errors to StandardError
process.BeginErrorReadLine();
// Wait for process to exit
await process.WaitForExitAsync();
}
start.Start();
while (!start.StandardOutput.EndOfStream)
{
string line = start.StandardOutput.ReadLine();
}
In my .NET Core Console app, I receive multiple commands in form of an array of string, and would like to execute them as console command (and showing their output in my own app if possible but not hard requirement).
At first, I tried to parse each command to separate their name and arguments and put them in ProcessStartInfo. However, some command does not work (even simple commands like echo "Hello").
Now I switched to call Powershell instead like this:
static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
{
return args
.Skip(1)
.Select(q => new ProcessStartInfo()
{
FileName = "powershell",
Arguments = q,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
}).ToList();
}
static void RunCommand(ProcessStartInfo processInfo)
{
Console.WriteLine($"{processInfo.Arguments}");
var process = new Process()
{
StartInfo = processInfo,
};
process.Start();
while (!process.StandardOutput.EndOfStream)
{
Console.WriteLine(process.StandardOutput.ReadLine());
}
process.WaitForExit();
}
The problem is I don't think this one can run on Linux or MacOS. Is there any "standard" way to tell my app to "run this as if it's a console command"?
This is my current code by using the Platform to determine the console command, feel free to tell me if there is a better way:
static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
{
var argsPrepend = "";
var shellName = "/bin/bash";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
shellName = "cmd";
argsPrepend = "/c ";
}
return args
.Skip(1)
.Select(q => new ProcessStartInfo()
{
FileName = shellName,
Arguments = argsPrepend + q,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
}).ToList();
}
static void RunCommand(ProcessStartInfo processInfo)
{
Console.WriteLine($"{processInfo.Arguments.Substring(processInfo.FileName == "cmd" ? 3 : 0)}");
var process = new Process()
{
StartInfo = processInfo,
};
process.Start();
while (!process.StandardOutput.EndOfStream)
{
Console.WriteLine(process.StandardOutput.ReadLine());
}
process.WaitForExit();
}
How to identify the hardware details of a Linux/Mac machine using.Net Core.
For windows machines, we can use System.Management and WMI Query.
So is there any similar way to identify the hardware details (like RAM ,Processor,Monitor ,CAM etc) of Linux and Mac machines.
For windows, I'm using:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("select * from Win32_Processor");
This is a piece of code to write bash linux commends in .net core:
using System;
using System.Diagnostics;
public static class ShellHelper
{
public static string Bash(this string cmd)
{
var escapedArgs = cmd.Replace("\"", "\\\"");
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
}
This is an extension method, you use it like this:
var output = "ps aux".Bash();
As for the commends, refer the Get Linux System and Hardware Details on the Command Line article on VITUX to help you out writing the commends, it lists most of the commends to collect system information on Linux.
For MAC:
System.Management.ManagementClass mc = default(System.Management.ManagementClass);
ManagementObject mo = default(ManagementObject);
mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (var mo in moc) {
if (mo.Item("IPEnabled") == true) {
Adapter.Items.Add("MAC " + mo.Item("MacAddress").ToString());
}
}
I have done a workaround to get hardware info as per Platform. For windows I have used old way of system Management classes, for Linux i have used different Bash commands to Get Processor Id, Model,model version,machine id.
Following are some linux commands i am using
1. "LinuxModel": "cat /sys/class/dmi/id/product_name"
2. "LinuxModelVersion": "cat /sys/class/dmi/id/product_version"
3. "LinuxProcessorId": "dmidecode -t processor | grep -E ID | sed 's/.*: //' | head -n 1"
4. "LinuxFirmwareVersion": "cat /sys/class/dmi/id/bios_version",
5. "LinuxMachineId": "cat /var/lib/dbus/machine-id"
Waiting for some support in the .net core framework soon
My gihub post address is https://github.com/dotnet/corefx/issues/22660
I have also used similar extension method with a bit optimized code for bash command
public static string Bash(this string cmd)
{
string result = String.Empty;
try
{
var escapedArgs = cmd.Replace("\"", "\\\"");
using (Process process = new Process())
{
process.StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
};
process.Start();
result = process.StandardOutput.ReadToEnd();
process.WaitForExit(1500);
process.Kill();
};
}
catch (Exception ex)
{
//Logger.ErrorFormat(ex.Message, ex);
}
return result;
}
We are writing a Xamarin.Mac application. We need to execute a command like "uptime" and read it's output into an application to parse.
Could this be done? In Swift and Objective-C there is NTask, but I don't seem to be able to find any examples in C#.
Under Mono/Xamarin.Mac, you can the "standard" .Net/C# Process Class as the Process gets mapped to the underlaying OS (OS-X For Mono, MonoMac and Xamarin.Mac, and Mono for *nix).
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// To avoid deadlocks, always read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Xamarin: https://developer.xamarin.com/api/type/System.Diagnostics.Process/
MSDN: https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Example from my OS-X C# code, but it is cross-platform as it works as is under Windows/OS-X/Linux, just the executable that you are running changes across the platforms.
var startInfo = new ProcessStartInfo () {
FileName = Path.Combine (commandPath, command),
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UserName = System.Environment.UserName
};
using (Process process = Process.Start (startInfo)) { // Monitor for exit}
process.WaitForExit ();
using (var output = process.StandardOutput) {
Console.Write ("Results: {0}", output.ReadLine ());
}
}
Here is an example taken from Xamarin forum:
var pipeOut = new NSPipe ();
var t = new NSTask();
t.LaunchPath = launchPath;
t.Arguments = launchArgs;
t.StandardOutput = pipeOut;
t.Launch ();
t.WaitUntilExit ();
t.Release ();
var result = pipeOut.ReadHandle.ReadDataToEndOfFile ().ToString ();