Run VB Script from Windows Service - c#

I have written a small Windows Service in C# which executes .BAT and .VBS scripts. The following code triggers the .vbs script:
string path = "C:\\Path\\To\\MyScript.vbs";
Process p = new Process();
p.StartInfo = new ProcessStartInfo();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WorkingDirectory = Environment.SystemDirectory;
p.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
p.StartInfo.Arguments = "/C C:\\Windows\\System32\\cscript.exe //Nologo \"" + path + "\"";
p.StartInfo.ErrorDialog = false;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.OutputDataReceived += OutputDataReceived;
p.ErrorDataReceived += OutputDataReceived;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
try
{
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
}
catch { // }
The code compiles and runs without any exceptions. However, there miust be something wrong since the VBS script does not execute until the end. Inside the script, I open a telnet session and enter some commands. When I run the same code and the same script in a WinForms Application, everything works perfectly fine.
I assume the problem is caused by my service, which runs as LOCAL SYSTEM.
Any ideas?
EDIT
This is my VBScript:
set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd"
WScript.Sleep 1000
WshShell.SendKeys "telnet 127.0.0.1 3000"
WshShell.SendKeys "{ENTER}"
WScript.Sleep 2000
WshShell.SendKeys "reboot application"
WshShell.SendKeys "{ENTER}"
WScript.Sleep 2000
For some reason, the telnet command is never executed, but the Process still ends with exitcode '0'...

Got it - SendKeys does not work when no user is logged in. The code itself works perfectly fine.

Related

Start NodeJS Application from C# web Form Application

I have built MeteroJS application that I want to start as NodeJS application from C# code.
Here is Windows Form application that is used as control panel for starting and stopping the NodeJS application
I can start NodeJS application manually with command line: (this works!)
set MONGO_URL=mongodb://someAdmin:password#localhost:27017/some_db
set ROOT_URL=http://someservice:8080
set PORT=8080
node bundle\main.js
I want to repeat all action above from command line, this time inside C# application.
This is code that executes on Start button click:
Environment.SetEnvironmentVariable("MONGO_URL", String.Format("mongodb://{0}:{1}#localhost:27017/{2}", usernameTxt.Text, passwordTxt.Text, databaseTxt.Text), EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("ROOT_URL", String.Format("http://someservice:{0}", portTxt.Text), EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("PORT", portTxt.Text, EnvironmentVariableTarget.Machine);
Process.Start("CMD.exe", #"/C node bundle\main.js");
I am not sure if this is even possible. This simply does not work and left no logs.
Could you please check what I am doing wrong and advise.
Use the following code to execute the node.js cmd
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.FileName = #"c:\node\node.exe";**//Path to node installed folder****
string argument = "\\ bundle\main.js";
p.StartInfo.Arguments = #argument;
p.Start();
This code may help you:
Process p = new Process();
p.StartInfo.WorkingDirectory= #"C:\Users\USERNAME\Documents\Visual Studio 2015\Projects\Proyecto 1.3\Proyecto 1.3\bin\Debug\server";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c node app.js";
p.Start();

Working with the command prompt in C#

I am working on a project of remotely receiving commands from a server, but I am facing a problem when working with the command prompt locally. Once I get it working locally, then I will move to remote communication.
Problem:
I have to completely hide the console, and client must not see any response when the client is working with the command line but it will show a console for a instance and then hide it.
I had to use c# to send a command to cmd.exe and receive the result back in C#. I have done it in one way by setting the StandardOutput... and input to true.
The commands are not working. For example, D: should change the directory to D and it does, but after that, if we use dir to see the directories in D, it does not show the appropriate directories.
Here is my code:
First Method
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C " + textBoxInputCommand.Text + " >> " + " system";
process.StartInfo = startInfo;
process.Start();
Second Method
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + textBoxInputCommand.Text);
procStartInfo.WorkingDirectory = #"c:\";
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = true;
procStartInfo.UseShellExecute = false;
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
richTextBoxCommandOutput.Text += result;
I want the program to run as administrator because the exe it generates does not run commands when it runs from the C drive.
Try not to run the commands by passing them to cmd instead write the commands passed by the client to a.bat file execute the .bat. file from your program this will probably hide your command prompt window.
You can also use process.OutputDataRecieved event handler to do anything with the output.
If you want to execute command using administrator rights you can use runascommand. It is equivalent to the sudo command in Linux. Here is a piece of code may be it will help you
var process = new Process();
var startinfo = new ProcessStartInfo(#"c:\users\Shashwat\Desktop\test.bat");
startinfo.RedirectStandardOutput = true;
startinfo.UseShellExecute = false;
process.StartInfo = startinfo;
process.OutputDataRecieved += DoSomething;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
//Event Handler
public void DoSomething(object sener, DataReceivedEventArgs args)
{
//Do something
}
Hope it helps you.
You could hide command prompt window by adding this line of code:
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
or do not create it at all
startInfo.CreateNoWindow = true;
Here can be found a few awarding solutions:
Run Command Prompt Commands

Child process not getting created when called from winform button event function?

I am trying to run a python code from my UI. i am using the code below to do so,
Process p = new Process();
string cmd = #"python filepath & exit";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.RedirectStandardInput = true;
p.Start();
StreamWriter myStreamWriter = p.StandardInput;
myStreamWriter.WriteLine(cmd.ToString());
myStreamWriter.Close();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();
the above code opens a cmd prompt and executes the python file.
this code runs fine when i test it using a console application but it doesn't work when i use it within the event function for "run" button in my UI application. Is there any particular reason for it?

Showing output of a running cmd process

I have a C# code that uses command prompt to call a python script. The script currently takes about 25 seconds to run. When run in command prompt, the python script has several outputs until finally outputting "done". My C# code runs the script, but never closes the command prompt if I use "WaitForExit". So my thought is I need some kind of logic to check to see if "done" has been outputted, but the internet has not been very helpful with methodology.
Here's what I have, it currently only outputs the first line, "Microsoft Windows [Version 6.1.7601]". Obviously, no good.
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.WorkingDirectory = #"C:\Optimization";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.Start();
p.StandardInput.WriteLine(#"ipy spot_for_labview.py");
StreamReader mySR = p.StandardOutput;
string mystr = mySR.ReadLine();
Debug.WriteLine(mystr);
p.WaitForExit(25000); //25000 is a placeholder until better method found.
p.Close();
If there's anyway to close the process after it finishes, or to get all the cmd output I'm all ears.
Any help is appreciated.
did you try this event ? Process.OutputDataReceived Event
or Process.ErrorDataReceived Event
here is the code from MSDN
Process sortProcess;
sortProcess = new Process();
sortProcess.StartInfo.FileName = "Sort.exe";
sortProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
...
....
...
private static void SortOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
}

Is this possible to run a python code from C# through command prompt?

I want to run python code from C# through command Prompt.The Code is attached below
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.WorkingDirectory = #"d:";
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.Start();
p.StandardInput.WriteLine(#"cd D:\python-source\mypgms");
p.StandardInput.WriteLine(#"main.py -i example-8.xml -o output-8.xml");
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);
Output :
D:\python-source\mypgms>main.py -i example-8.xml -o output-8.xml
D:\python-source\mypgms>
But nothing happened.Actually main.py is my main program and it takes 2 arguments. one is input xml file and another one is converted output xml file.
But i dont know how to run this python script from C# through command prompt. Please Guide me to get out of this issue...
Thanks & Regards,
P.SARAVANAN
I think you are mistaken in executing cmd.exe. I'd say you should be executing python.exe, or perhaps executing main.py with UseShellExecute set to true.
At the moment, your code blocks at p.WaitForExit() because cmd.exe is waiting for your input. You would need to type exit to make cmd.exe terminate. You could add this to your code:
p.StandardInput.WriteLine(#"exit");
But I would just cut out cmd.exe altogether and call python.exe directly. So far as I can see, cmd.exe is just adding extra complexity for absolutely no benefit.
I think you need something along these lines:
var p = new Process();
p.StartInfo.FileName = #"Python.exe";
p.StartInfo.Arguments = "main.py input.xml output.xml";
p.StartInfo.WorkingDirectory = #"D:\python-source \mypgms";
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
p.WaitForExit();
Also the Python script appears to output to a file rather than to stdout. So when you do p.StandardOutput.ReadToEnd() there will be nothing there.
Why not host IronPython in your app and then execute the script?
http://blogs.msdn.com/b/charlie/archive/2009/10/25/hosting-ironpython-in-a-c-4-0-program.aspx
http://www.codeproject.com/Articles/53611/Embedding-IronPython-in-a-C-Application
or use py2exe to pragmatically convert your python script to exe program.
detail steps...
download and install py2exe.
put your main.py input.xml and output.xml in c:\temp\
create setup.py and put it in folder above too
setup.py should contain...
from distutils.core import setup
import py2exe
setup(console=['main.py'])
your c# code then can be...
var proc = new Process();
proc.StartInfo.FileName = #"Python.exe";
proc.StartInfo.Arguments = #"setup.py py2exe";
proc.StartInfo.WorkingDirectory = #"C:\temp\";
proc.Start();
proc.WaitForExit();
proc.StartInfo.FileName = #"C:\temp\dist\main.exe";
proc.StartInfo.Arguments = "input.xml output.xml";
proc.Start();
proc.WaitForExit();

Categories

Resources