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
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
Good day guys.
Currently, I am developing a code to execute a Teraterm macro which I had saved as a *.ttl file. The name of the file is "new.ttl" and the content is as below:
showtt 0
filedelete 'a.txt'
pause 5
:Close
closett
So, the logic is just to delete "a.txt" file, wait for 5 seconds and close Teraterm. This new.ttl works perfectly when I run it manually using Teraterm, where I load the macro in the tab control>macro. This simple .ttl file is just for some trial for me before I start to write a more complex code.
Now, I tried to launch the .ttl file using C#. The code is as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;
namespace TeraTermConnect
{
class Program
{
static void Main(string[] args)
{
//Declare process for .ttl
Process process = new Process();
ProcessStartInfo start = new ProcessStartInfo();
//variables
string ttlpath = #"C:\TeraTermConnect\TeraTermConnect";
string ttl = "new.ttl";
string ttpHidden = #"/V";
//start the .ttl file
start.FileName = ttlpath;
start.Arguments = ttpHidden + ttl;
start.UseShellExecute = false;
//Tried a lot of thing here, not sure how to run the .ttl
Process.Start(start);
Thread.Sleep(5000);
Console.WriteLine("The process is over");
Console.WriteLine();
Console.WriteLine("Check the text file...");
Console.WriteLine();
Console.WriteLine("Hit enter to exit...");
Console.ReadKey();
}
}
}
The execution runs without any error, but, the result is not as expected. After the execution, I can see "a.txt" is still inside the mentioned path as in the code. I am not sure where I went wrong. This is just a starting step for me before I develop a more complex .ttl file and execute it through c#.
Your help is deeply appreciated. Thank you very much.
Good day guys,
After 2 days of struggle, I managed to get the answer.
using System;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace TeraTermConnect
{
class Program
{
static void Main(string[] args)
{
//Declare process for .ttl
Process process = new Process();
ProcessStartInfo start = new ProcessStartInfo();
//variables
string ttlpath = #"C:\Program Files (x86)\teraterm\" + #"TTPMACRO";
string ttl = "new.ttl";
string ttpHidden = #"/V ";
ProcessStartInfo start = new ProcessStartInfo();
//start the .ttl file
start.FileName = ttlpath;
start.Arguments = ttpHidden + ttl;
start.UseShellExecute = false;
process.StartInfo = start;
try
{
Process.Start(start);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Console.WriteLine("The process is over");
Console.WriteLine();
Console.WriteLine("Check the text file...");
Console.WriteLine();
Console.WriteLine("Hit enter to exit...");
Console.ReadKey();
}
}
}
The version of Teraterm that i am currently using is 4.94 and I had also installed TTLEditor version 1.5 to create the .TTL file. It seems that the problem was,
1) To execute a .TTL file programmatically from C#, I need to place the .TTL file in the same folder where TTPMACRO.EXE and TTERMPRO.EXE is located in my system. This is shown by the string value ttlpath in my code.
2) In the ttlpath, the string value #"TTPMACRO" need to be added to the folder as this will make the .TTL file to be executable.
And, for your info, in my system, the text file a.txt that will be deleted if the logic of the .TTL file is executed is located at:
C:\Users\Admin\AppData\Local\VirtualStore\Program Files (x86)\teraterm
For more info on how to run teraterm macro files, refer to this link;
https://ttssh2.osdn.jp/manual/en/macro/howtorun.html
have a nice day..
Hari
As I aksed in another post, I am trying to automate running processing ide from c#. Finally I found the way to run the processing sketch via cmd, with setting the installed processing folder in the path of evironment variable.
I find it works with inputting command directly in cmd.exe, but when I want to do the same thing through some c# code in Visual Studio, it doesn't run the .pde file.
Here is the code,
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Runprocessing
{
static void Main()
{
Process process = new Process();
ProcessStartInfo stinfo = new ProcessStartInfo();
stinfo.FileName = "cmd.exe";
stinfo.Arguments = "/c"+"processing-java --run --sketch=D:\\pw --output=D:\\pw\\output";
stinfo.CreateNoWindow = true;
stinfo.UseShellExecute = false;
process = Process.Start(stinfo);
process.WaitForExit();
process.Close();
process.Dispose();
}
}
}
My question is, how should I properly use processing-java to activate the sketch. because here I am stating
stinfo.FileName = "cmd.exe";
stinfo.Arguments = "/c"+"processing-java --run --sketch=D:\\pw --output=D:\\pw\\output";
Is this the right way to use processing-java in cmd?
I found this thread very helpful and I would like to ask Ian Norton about his wrapper. HERE is the link to the wrapper I was trying that IanNorton had posted. I'm not sure if this is the right place to ask and I also don't want to create a new thread when it pertains to his response. So I will go ahead and suffer whatever backlash may come my way.
I am currently trying to use your wrapper and i cannot seem to seem to get it to trigger anything when I run it. I do not want to use options as i just want to set this as an .exe that runs on a timer. Quite simply, I would like to use the p4 opened -a cmd and print the out puts to a file. That is it. Any help would be greatly appreciated by this NooB.
Thank you very much!
This is as far as I got with just using the Command Line. Unfortunately I could not output my info to a text file.
using System;
using System.Diagnostics;
using System.IO;
namespace P4OpenCMD
{
class P4Opened
{
// Main begins program execution.
static void Main(string[] args)
{
string temp = string.Empty;
if (temp != string.Empty)
{
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
StreamWriter sw = p.StandardInput;
using (sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("set P4PORT=####");
sw.WriteLine("set P4USER=####");
sw.WriteLine("set P4CLIENT=####");
sw.WriteLine("set P4PASSWD=####");
sw.WriteLine("p4 opened -a //Depot/...");
sw.WriteLine("pause;");
}
Console.WriteLine();
}
sw.Close();
p.WaitForExit();
p.Close();
}
}
}
}
If you do this, you should be in good shape:
info.FileName = "cmd.exe";
info.Arguments = "/c p4 opened > opened.txt";
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#