I have a C# app application working to some extent. What i need to do is to continue execution if a computer (given an IP Address) is running an application (TEKBSS.exe). How can i do that? Can someone help me?
You can do this through WMI. You'll need appropriate credentials to access the remote machine.
The System.Management namespace includes features for using WMI from C#.
Here you go:
// Don't forget...
// using System.Management; <-- Need to add a reference to System.Management, too.
ManagementScope scope = new ManagementScope(#"\\192.168.1.73\root\cimv2");
string query = "SELECT * FROM Win32_Process WHERE Name='TEKBSS.exe'";
var searcher = new ManagementObjectSearcher(query);
searcher.Scope = scope;
bool isRunning = searcher.Get().Count > 0;
The scope tells WMI what machine to execute the query on, so don't forget to change the IP address accordingly.
The ManagementObjectSearcher will then query the machine for a list of all processes with the name TEKBSS.exe.
You can use WMI to query information on remote machines, such as which programs are running.
You will need to reference System.Management.dll, and have appropriate rights on the remote machine to access WMI.
using System;
using System.Linq;
using System.Management;
namespace Bling
{
public static void Main()
{
const string Host = "vmhost01";
const string Path = (#"\\" + Host + #"\root\CIMV2");
const string Exe = "TEKBSS.exe";
var queryString = string.Format("SELECT Name FROM Win32_Process WHERE Name = '{0}'", Exe);
var query = new SelectQuery(queryString);
var options = new ConnectionOptions();
options.Username = "Administrator";
options.Password = "*";
var scope = new ManagementScope(Path, options);
var searcher = new ManagementObjectSearcher(scope, query);
bool isRunnning = searcher.Get().Count > 0;
Console.WriteLine("Is {0} running = {1}.", Exe, isRunnning);
}
}
Look into:
System.Diagnostics.Process
Process p = new Process();
p.StartInfo.FileName = "TEKBSS.exe";
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
EDIT:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Security;
public class MainClass
{
public static void Main()
{
Process[] allProcs = Process.GetProcesses("RemoteMachineOnYourNetwork");
foreach (Process p in allProcs)
Console.WriteLine(" -> {0} - {1}", p.ProcessName, p.PeakWorkingSet64);
}
}
I know this is .net code. But I used this a while ago to do the same. Hopefully it will give you an idea, and I will try and convert. As long as you have permission rights you can execute the command pushd in your code. You can try executing from the command line first to make sure you can get in.
PushD
//pushes into the Given Machine on the C:\ and filters for your program
Dim sCommand as String = "pushd \\<MachineName>\C$ && tasklist.exe /FI ""IMAGENAME eq <NameOfExecutable>.exe""
//execute command from program
Shell("cmd.exe /c" & sCommand. AppWinStyle.Hide, True);
You will most likely want to execute popd after to return to the directory on your machine.
Let me see if I can convert to C for you. I will edit in a bit.
EDIT
Link to executing commands in C#
Related
This sort of question has been asked before in varying degrees, but I feel it has not been answered in a concise way and so I ask it again.
I want to run a script in Python. Let's say it's this:
if __name__ == '__main__':
with open(sys.argv[1], 'r') as f:
s = f.read()
print s
Which gets a file location, reads it, then prints its contents. Not so complicated.
Okay, so how do I run this in C#?
This is what I have now:
private void run_cmd(string cmd, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = cmd;
start.Arguments = args;
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
}
When I pass the code.py location as cmd and the filename location as args it doesn't work. I was told I should pass python.exe as the cmd, and then code.py filename as the args.
I have been looking for a while now and can only find people suggesting to use IronPython or such. But there must be a way to call a Python script from C#.
Some clarification:
I need to run it from C#, I need to capture the output, and I can't use IronPython or anything else. Whatever hack you have will be fine.
P.S.: The actual Python code I'm running is much more complex than this, and it returns output which I need in C#, and the C# code will be constantly calling the Python code.
Pretend this is my code:
private void get_vals()
{
for (int i = 0; i < 100; i++)
{
run_cmd("code.py", i);
}
}
The reason it isn't working is because you have UseShellExecute = false.
If you don't use the shell, you will have to supply the complete path to the python executable as FileName, and build the Arguments string to supply both your script and the file you want to read.
Also note, that you can't RedirectStandardOutput unless UseShellExecute = false.
I'm not quite sure how the argument string should be formatted for python, but you will need something like this:
private void run_cmd(string cmd, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "my/full/path/to/python.exe";
start.Arguments = string.Format("{0} {1}", cmd, args);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using(Process process = Process.Start(start))
{
using(StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
}
If you're willing to use IronPython, you can execute scripts directly in C#:
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
private static void doPython()
{
ScriptEngine engine = Python.CreateEngine();
engine.ExecuteFile(#"test.py");
}
Get IronPython here.
Execute Python script from C
Create a C# project and write the following code.
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
run_cmd();
}
private void run_cmd()
{
string fileName = #"C:\sample_script.py";
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"C:\Python27\python.exe", fileName)
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();
}
}
}
Python sample_script
print "Python C# Test"
You will see the 'Python C# Test' in the console of C#.
I ran into the same problem and Master Morality's answer didn't do it for me. The following, which is based on the previous answer, worked:
private void run_cmd(string cmd, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = cmd;//cmd is full path to python.exe
start.Arguments = args;//args is path to .py file and any cmd line args
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using(Process process = Process.Start(start))
{
using(StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
}
As an example, cmd would be #C:/Python26/python.exe and args would be C://Python26//test.py 100 if you wanted to execute test.py with cmd line argument 100. Note that the path the .py file does not have the # symbol.
Actually its pretty easy to make integration between Csharp (VS) and Python with IronPython. It's not that much complex... As Chris Dunaway already said in answer section I started to build this inegration for my own project. N its pretty simple.
Just follow these steps N you will get your results.
step 1 : Open VS and create new empty ConsoleApp project.
step 2 : Go to tools --> NuGet Package Manager --> Package Manager Console.
step 3 : After this open this link in your browser and copy the NuGet Command.
Link: https://www.nuget.org/packages/IronPython/2.7.9
step 4 : After opening the above link copy the PM>Install-Package IronPython -Version 2.7.9
command and paste it in NuGet Console in VS.
It will install the supportive packages.
step 5 : This is my code that I have used to run a .py file stored in my Python.exe
directory.
using IronPython.Hosting;//for DLHE
using Microsoft.Scripting.Hosting;//provides scripting abilities comparable to batch files
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
class Hi
{
private static void Main(string []args)
{
Process process = new Process(); //to make a process call
ScriptEngine engine = Python.CreateEngine(); //For Engine to initiate the script
engine.ExecuteFile(#"C:\Users\daulmalik\AppData\Local\Programs\Python\Python37\p1.py");//Path of my .py file that I would like to see running in console after running my .cs file from VS.//process.StandardInput.Flush();
process.StandardInput.Close();//to close
process.WaitForExit();//to hold the process i.e. cmd screen as output
}
}
step 6 : save and execute the code
Set WorkingDirectory or specify the full path of the python script in the Argument
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "C:\\Python27\\python.exe";
//start.WorkingDirectory = #"D:\script";
start.Arguments = string.Format("D:\\script\\test.py -a {0} -b {1} ", "some param", "some other param");
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
I am having problems with stdin/stout - when payload size exceeds several kilobytes it hangs. I need to call Python functions not only with some short arguments, but with a custom payload that could be big.
A while ago, I wrote a virtual actor library that allows to distribute task on different machines via Redis. To call Python code, I added functionality to listen for messages from Python, process them and return results back to .NET.
Here is a brief description of how it works.
It works on a single machine as well, but requires a Redis instance. Redis adds some reliability guarantees - payload is stored until a worked acknowledges completion. If a worked dies, the payload is returned to a job queue and then is reprocessed by another worker.
had same issure and this worked for me:
using IronPython.Hosting;
var engine = Python.CreateEngine();
engine.ExecuteFile("") //put the directory of the program in the quote marks
I'm creating a website and in it I'm giving a link where the user enters his/her Azure VM username and password and then I'm gonna go ahead and restart the machine IIS server.
So I'm writing a .NET Code for implementing the same but no luck yet. I'm not able to restart the IIS server for the remote machines, I have even looked for an alternative approach to achieve the same using Powershell but unable to do so.
I tried remotely restarting the IIS server using WMI and also created code for calling Powershell in .Net Core but I'm not able to achieve the same.
Can someone please help me with how to restart the IIS server remotely using C# code or .NET Core code?
As for this...
Share me the link wherein there is a PowerShell script that restarts
IIS on a remote server using the system credentials.
... a quick search using 'Restart IIS on remote machine'
... will give a list of articles in the topic, some from right here on StackOverflow, since this is not the first time this has been asked. So, your question can be considered a potential duplicate of the below.
Example(s):
about_Remote - PowerShell | Microsoft Docs
Restart IIS on remote machine
Some of the answers, not using PowerShell to do this from the above are:
# Simplest will be
iisreset <servername>
# Run command prompt as admin and execute the command.
# Example : If server name is SRVAPP then command will be iisreset SRVAPP
# You could use sc
sc \\RemoteServer stop iisadmin
sc \\RemoteServer start w3svc
# or SysInternals' psexec. The PsTools suite is useful for these scenarios.
psexec \\RemoteServer iisreset
PowerShell Remoting requires you to be in the local admin group on the target host. You cannot run PowerShell code as SYSTEM unless you are running a scheduled task, even then it is the scheduled task running as whatever credential it was set for and running any script in that task. To run PowerShell code as another user, you must know the username and password.
You can use PowerShell to set up a scheduled task to run. Just search for 'PowerShell scheduled task' for details.
I tried the below codes for restarting IIS remotely but it didn't work.
Method 1:
using System.Diagnostics;
using System.Management;
using System.IO;
using System.Security;
Process myProcess = new Process();
ProcessStartInfo remoteAdmin =
new ProcessStartInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "iisreset.exe"));
remoteAdmin.Arguments = "/restart";
myProcess.StartInfo.Verb = "runas";
var s = new SecureString();
//s.AppendChar('g');
Console.WriteLine("Enter username:");
string userName = Console.ReadLine();
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Enter password:");
string password = Console.ReadLine();
Console.WriteLine(Environment.NewLine);
var securePasswordString = new SecureString();
// Use ToCharArray to convert string to array.
char[] array = password.ToCharArray();
// Loop through array.
for (int i = 0; i < array.Length; i++)
{
// Get character from the array.
securePasswordString.AppendChar(array[i]);
}
remoteAdmin.UserName = userName;
remoteAdmin.Password = securePasswordString;
remoteAdmin.Domain = "localhost";
myProcess.StartInfo = remoteAdmin;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.Start(); //---ERROR HERE
if (!myProcess.Start())
{
// That didn't work
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Process did not start!!!");
}
myProcess.WaitForExit();
var processExitCode = myProcess.ExitCode;
if (processExitCode == 0)
{
Console.WriteLine("The operation completed successfully.");
}
if (processExitCode != 0)
{
// That didn't work
if (processExitCode == 5)
{
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Access Denied");
}
}
Console.ReadKey();
Method 2:
ConnectionOptions conn = new ConnectionOptions();
conn.Impersonation = ImpersonationLevel.Impersonate;
conn.Username = #"Username";
conn.Password = "";
//ManagementScope theScope = new ManagementScope("\\\\" + txtServerName.Text + "\\root\\cimv2", conn);
theScope.Connect(); //---ERROR HERE
I tried the below code to run powershell script from C# code but I need the script which takes remote server admin credentials and restart the IIS.
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
static void RunPsScriptMethod2()
{
StringBuilder sb = new StringBuilder();
PowerShell psExec = PowerShell.Create();
psExec.AddCommand(#"C:\Users\d92495j\Desktop\test.ps1");
psExec.AddArgument(DateTime.Now);
Collection<PSObject> results;
Collection<ErrorRecord> errors;
results = psExec.Invoke();
errors = psExec.Streams.Error.ReadAll();
if (errors.Count > 0)
{
foreach (ErrorRecord error in errors)
{
sb.AppendLine(error.ToString());
}
}
else
{
foreach (PSObject result in results)
{
sb.AppendLine(result.ToString());
}
}
Console.WriteLine(sb.ToString());
}
I want to open process pon remote machine, this remote machine is inside local network.
I try this command and in the remote machine nothing happen, this user that i connect with have administrators rights.
Both machines running Windows 7
static void Main(string[] args)
{
try
{
//Assign the name of the process you want to kill on the remote machine
string processName = "notepad.exe";
//Assign the user name and password of the account to ConnectionOptions object
//which have administrative privilege on the remote machine.
ConnectionOptions connectoptions = new ConnectionOptions();
connectoptions.Username = #"MyDomain\MyUser";
connectoptions.Password = "12345678";
//IP Address of the remote machine
string ipAddress = "192.168.0.100";
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + #"\root\cimv2", connectoptions);
//Define the WMI query to be executed on the remote machine
SelectQuery query = new SelectQuery("select * from Win32_process where name = '" + processName + "'");
object[] methodArgs = { "notepad.exe", null, null, 0 };
using (ManagementObjectSearcher searcher = new
ManagementObjectSearcher(scope, query))
{
foreach (ManagementObject process in searcher.Get())
{
//process.InvokeMethod("Terminate", null);
process.InvokeMethod("Create", methodArgs);
}
}
Console.ReadLine();
}
catch (Exception ex)
{
//Log exception in exception log.
//Logger.WriteEntry(ex.StackTrace);
Console.WriteLine(ex.StackTrace);
}
}
you are not opening a process with that code but you are enumerating all the running process named "iexplore.exe" and close them.
I think an easier, better way is to use SysInternals PsExec or the Task Scheduler API
If you want to use WMI your code should look like this:
object theProcessToRun = { "YourFileHere" };
ManagementClass theClass = new ManagementClass(#"\\server\root\cimv2:Win32_Process");
theClass.InvokeMethod("Create", theProcessToRun);
----------In reply to your comment------------------
First of all you need to change your attitude and approach to coding and read the code that your are copy/pasting.
Then you should study a little more about programming languages.
No I will not write the code for you. I gave you an hint to point to the right direction. now it is your turn to develop it. Have fun!!
This is script that i did for my company before this using vbs script. can search the net to convert it to C# or etc. Fundamental of the steps and how to start a service using WMI. Have a nice coding and have fun.
sUser = "TESTDomain\T-CL-S"
sPass = "Temp1234"
Set ServiceSet = GetObject("winmgmts:").ExecQuery("Select * from Win32_Service where Name = 'netlogon'")
For Each Service In ServiceSet
Service.StopService
Service.Change "netlogon",Service.PathName, , ,"Automatic",false,sUser,sPass
Service.StartService
Next
Set Service = Nothing
Set ServiceSet = Nothing
I’m trying to write a small Windows Forms GUI that would take in the text of a WMI query, and have the output/results of that WMI query displayed inside a textbox on the Form.
For testing purposes to prove things are working, I’m trying to get the GUI to write the WMI output to the command line Console, but I’m having no luck with displaying the output so far.
Where am I going wrong (I'm new to C#, so that's gonna be a long list!)?
This is the code behind the Form I'm working with...
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.Management;
namespace WMI_Form1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_runQuery_Click(object sender, EventArgs e)
{
string _userName = textBox1_userName.Text;
string _passWord = textBox2_password.Text;
string _serverName = textBox3_serverName.Text;
string _wmiQuery = textBox4_queryInput.Text;
EnumServices(_serverName, _userName, _passWord);
}
static void EnumServices(string host, string username, string password)
{
string ns = #"root\cimv2";
string query = "SELECT * FROM Win32_LogicalDisk";
//string query = "select * from Win32_Service";
ConnectionOptions options = new ConnectionOptions();
if (!string.IsNullOrEmpty(username))
{
options.Username = username;
options.Password = password;
}
ManagementScope scope =
new ManagementScope(string.Format(#"\\{0}\{1}", host, ns), options);
scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, new ObjectQuery(query));
ManagementObjectCollection retObjectCollection = searcher.Get();
foreach (ManagementObject mo in searcher.Get())
{
Console.WriteLine("Trying to output the results...");
Console.WriteLine(mo.GetText(TextFormat.Mof));
}
}
}
}
Because your project is a "Windows" application and not a "Console" application, you don't have a displayed/attached console window....thus the Console.WriteLine output has nowhere to go.
Instead of going through the trouble of creating a "console" for your GUI application (e.g. via AllocConsole - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682528(v=vs.85).aspx) which would then allow your Console.WriteLine output to be seen....it's not necessary in this case...as eventually you will be outputting into a ListBox...and you just want a quick way to "see" the data.
The quickest way to do that is with a "Trace" or "Debug" output statement:
(What’s the difference between the Debug class and Trace class?):
So:
System.Diagnostics.Trace.WriteLine("Trying to output the results...");
System.Diagnostics.Trace.WriteLine(mo.GetText(TextFormat.Mof));
or
System.Diagnostics.Debug.WriteLine("Trying to output the results...");
System.Diagnostics.Debug.WriteLine(mo.GetText(TextFormat.Mof));
The output will then appear in your "Output" window of Visual Studio if you run the "debug" build of your program from it.
If you start your program outside of Visual Studio, then you can use DebugView (http://technet.microsoft.com/en-gb/sysinternals/bb896647.aspx) to see the debug output.
After you have confirmed it's working, you can then put in the logic to add the output into a ListBox instead.
Below is the scenario.
Logged in to windows using user name "JOHN"
Run the Windows application writtern in c# . This tool name is BootStrapper.exe. But this tool I executed using different user called "ALEX" using Run As feature.
Boot strapper will show some button called "Launch Application". On clicking Launch executing Application.exe using Process class of c#. Note that i am not passing any user name and password. So Application.exe is also running under "ALEX" User.
How do I run the Application.exe under "JOHN" from Bootstrapper.exe even though it is started by "ALEX".
Note that the password of the "JOHN" will not be known to Application.exe to impersonate JOHN user.
Host a WCF service in a process started by JOHN (maybe by putting it in the startup folder).
Call the WCF service from the ALEX process with a command telling what process to start.
Start the process from the WCF service and it will be running as JOHN.
I apologize for my bad English. Maybe I wrong understand you... Compile it, and copy result to "C:\test" directory. Now run it.
using System;
using System.Text;
using System.Diagnostics;
using System.Security;
using System.Reflection;
using System.IO;
namespace ConsoleApplication6 {
class Program {
unsafe static void Main(string[] args) {
Process process = new Process();
String dir = Path.GetDirectoryName(typeof(Program).Assembly.Location);
String txtFile = Path.Combine(dir, "example.txt");
if (!File.Exists(txtFile)) {
StreamWriter sw = File.CreateText(txtFile);
sw.Close();
sw.Dispose();
}
ProcessStartInfo info = new ProcessStartInfo();
info.Domain = "myDomainName";
info.UserName = "userName";
String pass = "userPassword";
fixed (char* password = pass) {
info.Password = new SecureString(password, pass.Length);
}
// Will be run notepad.exe
info.FileName = Environment.ExpandEnvironmentVariables(#"%winDir%\NOTEPAD.EXE");
// in notepad.exe will be open example.txt file.
info.Arguments = txtFile;
info.LoadUserProfile = false;
info.UseShellExecute = false;
info.WorkingDirectory = dir;
process.StartInfo = info;
process.Start();
}
}
}
Regards