Runing command into CMD and get output into variable using C# - c#

I need to run a command into CMD window and want to get result into a variable.
I used below code to do the same but the out put is incorrect
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = " wmic.exe /node:(computername or ip address) computersystem get username ",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string line = "";
while (!proc.StandardOutput.EndOfStream)
{
line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
}
proc.WaitForExit();
Out put
Microsoft Windows [Version 6.1.7601]-----Copyright (c) 2009 Microsoft Corporation. All rights reserved.----------C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0>
But when i run this command into CMD window it shows the current logged in users name.
Can any one help me to solve the issue.
Note :- The given command is used to get the current logged in users
name on network system by using it's IP Address.

What you need is the /c option for cmd
C:\>cmd /?
Starts a new instance of the Windows command interpreter
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]
/C Carries out the command specified by string and then terminates
I would question the need for cmd.exe here. You can just invoke wmic directly as below
var proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "wmic.exe",
Arguments = "/node:localhost computersystem get username ",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string line = "";
while (!proc.StandardOutput.EndOfStream) {
line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
}
proc.WaitForExit();

Why would you go to the trouble of invoking a commandline tool and parsing its results if System.Management has all the classes you need to obtain the information in-process and managed?
var ip = "127.0.0.1";
var scope = new ManagementScope(
String.Format("\\\\{0}\\root\\cimv2", ip),
new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate });
scope.Connect();
var users = new ManagementObjectSearcher(
scope,
new ObjectQuery("Select * from Win32_LoggedonUser"))
.Get()
.GetEnumerator();
while(users.MoveNext())
{
var user = users.Current["antecedent"];
var mo = new ManagementObject(new ManagementPath(user.ToString()));
try
{
var username = mo.Properties["name"];
Console.WriteLine("username {0}", username.Value);
}
catch
{
Console.WriteLine(mo);
}
}
All you have to do is create a ManagementScope and then use the ManagementObjectSearcher to run any WMI Query Language statement by using one of the available WMI Classes.
If you have a working wmic call you can always add /TRACE:ON so you can inspect the calls being made. Use wmic /? to see the aliasses.

Related

How to identify the hardware details of a Linux/Mac machine using .Net Core

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;
}

Running command prompt using webapi but does not have permission

I'm trying to do a web api which allows my to start/stop/reset my application pools and sites inside IIS.
Currently, I have tested that running administration level Visual studio allows me to run my code flawlessly. But once I'm not running visual studio with administration level privileged, or even deployed to IIS and run as a test service, my method inside breaks.
A little overview of how it is done is I get a Process to run CMD which utilizes the appcmd to list and reset the iis connections.
private List<SiteModels> GetSiteModels()
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo
{
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Minimized,
FileName = "cmd.exe",
WorkingDirectory = #"C:\",
Arguments = "/K appcmd list sites & exit",
Verb = "runas",
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.EnableRaisingEvents = false;
List<SiteModels> sitesModelList = new List<SiteModels>();
string tempString = process.StandardOutput.ReadToEnd();
process.WaitForExit();
foreach (var line in tempString.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
{
SiteModels sitesModel = new SiteModels();
string pattern = "SITE \"(?<SiteName>.*?)\"[\\s\\S]*?id:(?<Id>.*?),[\\s\\S]*?bindings:(?<Bindings>.*?),[\\s\\S]*?state:(?<State>.*?)\\)";
Regex regexPattern = new Regex(pattern);
Match match = regexPattern.Match(line);
if (match.Success)
{
sitesModel.SiteName = match.Groups["SiteName"].Value.Trim();
sitesModel.Id = int.Parse(match.Groups["Id"].Value.Trim());
sitesModel.Bindings = match.Groups["Bindings"].Value.Trim();
sitesModel.State = match.Groups["State"].Value.Trim();
sitesModelList.Add(sitesModel);
}
}
return sitesModelList;
}

Process.WaitForExit() Much Slower After Refactor When Calling Taskkill

I am in the process of rewriting an application I made some time ago. One of the functions available to users is to enumerate all processes which are currently running over the active Citrix session and display them (Similar Windows Task Manager). The issue is when querying tasklist on the user's machine, and the length of time taken to output the results of this command.
My new version of the code takes a much more Object-Oriented approach by using non-static classes to represent Sessions and Procs (Processes).
The original code looked like this, and it worked fairly well in terms of length of time taken to actually run the query and retrieve the output results:
OLD CODE:
public static Dictionary<string, string> GetProcs(string server, string sessID)
{
SecureString ss = CreatePW();
ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/C tasklist /S " + server + " /FI \"SESSION eq " + sessID + "\" /FO CSV /NH")
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = #"C:\windows\system32",
Verb = "runas",
Domain = "BARDOM1",
UserName = "zzkillcitrix",
Password = ss
};
List<string> procList = new List<string>();
Process proc = Process.Start(startInfo);
proc.OutputDataReceived += (x, y) => procList.Add(y.Data);
proc.BeginOutputReadLine();
proc.WaitForExit();
// Create a new ditionary ...
Dictionary<string, string> procDict = new Dictionary<string, string>();
for (int i = 0; i < procList.Count - 1; i++)
{
if (procDict.ContainsKey(procList[i].Split(',')[0].Trim('"')))
{
// Do nothing
}
else
{
procDict.Add(procList[i].Split(',')[0].Trim('"'), procList[i].Split(',')[1].Trim('"'));
}
}
return procDict;
}
This entire application as very messy and so I've rewritten most of it, but my only concern is that the new method for retrieving the current list of processes is a lot slower (probably around 4 - 5 times slower than the old version).
NEW CODE:
In the ProcessHelper class
public static List<Proc> GetProcList(Session session)
{
// Get the current tasks
List<string> processQueryResult = TaskList(session);
List<Proc> procList = new List<Proc>();
foreach (var processDetails in processQueryResult)
{
// Only create the Proc if the process is in the 'valid' array ...
// Get the procname
string procName = processDetails.Split(',')[0].Trim('"').ToUpper();
// Make sure it's position is not -1 ...
int pos = Array.IndexOf(MyGlobals.ProcArray, procName);
if (pos > -1)
{
int procId = Int32.Parse(processDetails.Split(',')[1].Trim('"'));
Proc p = new Proc(procName, procId, session.ServerName, session.ID);
procList.Add(p);
SupportMI.Trace = "--adding" + p.Name + "--";
}
}
return procList;
}
private static List<string> TaskList(Session session)
{
string cmdIn = "tasklist /S " + session.ServerName + " /FI \"SESSION eq " + session.ID + "\" /FO CSV /NH";
List<string> cmdOut = Cmd.StdOutAdminList(cmdIn);
return cmdOut;
}
In the Cmd class
public static List<string> StdOutAdminList(string args)
{
List<string> cmdOut = new List<string>();
SecureString ss = pw();
ProcessStartInfo startInfo = new ProcessStartInfo("cmd", "/C " + args)
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = #"C:\windows\system32",
Verb = "runas",
Domain = "BARDOM1",
UserName = "zzkillcitrix",
Password = ss
};
cmdOut = ExecuteListCommand(startInfo);
return cmdOut;
}
private static List<string> ExecuteListCommand(ProcessStartInfo startInfo)
{
List<string> procList = new List<string>();
Process p = Process.Start(startInfo);
p.OutputDataReceived += (x, y) => procList.Add(y.Data);
p.BeginOutputReadLine();
p.WaitForExit();
return procList;
}
Possible Reasons
In the new version of the Program I also introduced several new objects (For example a Session class and a Proc class to store information about separate processes). Is it possible that adding these extra classes slows down the Process.WaitForExit() method?
After some debugging, it seems that the point at which the program is slowing down relative to the old code is when Process.WaitForExit() is called - Does anything affect this method call apart from the ProcessStartInfo details? if not, then I am very confused as I set the ProcessStarInfos to the same settings but still the new code has a delay.
Another thought I had was that perhaps the addition of more objects, meaning more parameters being passed around, is slowing down the whole application, which is somehow manifesting itself in the way described above.
Any insight into why this may be happening is much appreciated. Please let me know if I can provide any more details or code, or run any tests.
I also considered calling "tasklist" directly from Process rather than "cmd", but this had no affect, so I have ruled this out as a possibility.
This was due to the query not including the domain name after the server name.
I ran several tests using C# Stopwatch class, and it seems that running this query:
TASKLIST /S XA7-17
Is a lot slower than running
TASKLIST /S XA7-17.domain.co.uk
After including the domain name at the end of the server, my queries are just as fast a in the old application.

SharpPcap get Process Name

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);
}
}

OS Information of networkclient using C#

I'm working on an application which scans a given networkrange for computers. From the found clients I need to get the IP, hostname, Mac address, OS Information etc.
Now, I have all of the above, except the OS version. Does anyone have a clue on how I could achieve this?
I'm stuck.
Thanks in advance, Christophe
You could run Nmap using Process class from System.Diagnostics and parse the result:
var process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = "/c nmap -O -v targethost",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true
}
};
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
// here you can parse to obtain the operating system
}
Creating your own OS detector in C# would be hard but if you are interested in an overview of how it works you can find it in this Nmap chapter: Chapter 8. Remote OS Detection
Use WMI, add reference to - System.Management dll and provide namespace, use following code with appropriate parameters-
ManagementScope scope = new ManagementScope();
try
{
ConnectionOptions conOptions = new ConnectionOptions();
options.Username = "<Provide username>";
options.Password = "<Provide password>";
options.EnablePrivileges = true;
options.Authority = "ntlmdomain:<domianname>";
scope = new ManagementScope(#"\\<IP address/machine name>\root\CIMV2", options);
scope.Connect();
SelectQuery query = new SelectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
using (ManagementObjectCollection queryCollection = searcher.Get())
{
foreach (ManagementObject m in queryCollection)
{
Console.WriteLine(string.Format("Computer Name : {0}", m["csname"]));
Console.WriteLine(string.Format("Windows Directory : {0}", m["WindowsDirectory"]));
Console.WriteLine(string.Format("Operating System: {0}", m["Caption"]));
Console.WriteLine(string.Format("Version: {0}", m["Version"]);
Console.WriteLine(string.Format("Manufacturer : {0}", m["Manufacturer"]));
}
}
}
catch (Exception ex)
{
}
You must have access right to steal this info else you will get Access right exception.

Categories

Resources