Run Custom Command in C# Windows Service - c#

I have a custom console command, which if executed in command prompt just displays some text in the command window (similar to 'dir' command).
I'm trying to execute the command 'myCommand' from a windows service and it is always returning blank string values. However, if run the same command in a command prompt, the result is displayed in the command window. Also, if I run the below code in a windows forms application, it works fine and I get the same data which is displayed in the command screen to a string variable.
Where am I going wrong? Why is the code returning a blank string when I execute it from a windows service, where as it works in a forms application. Is there any other method to capture the result of a command to a string variable in a windows service? Please advise. Thank you.
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c myCommand");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();

Attach the Visual Studio debugger to your running service (Debug menu, Attach to Process), put a breakpoint in the code where you execute the the command, and then execute the comand. This will enable you to debug the problem. If necessary, you can call the System.Diagnostics.Debugger.Break method in your service to force it to break into the debugger at the appropriate point, without having to attach the debugger first.
Edit:
I suggest you also capture the standard error stream:
procStartInfo.RedirectStandardError = true;
...
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
Check what you get in the error string. I use WaitForExit to wait until the command exits too.

You are not setting the working Directory (ie procStartInfo.WorkingDirectory), so if the system can not find 'myCommand' , you will get this result.
Even if 'myCommand' is in the same directory as your service exe file, that does not normally work as the working directory for a service is normally windows\system32.

I preferred this Easier way to debug a C# Windows Service
I added the conditional If to launch the debugger from the OnStart method, then put a breakpoint in my OnCustomCommand(int command) method.

Related

See the window of a batch file that I start from IIS ASP.NET WebAPI thread

In my project I need to start a batch file from a thread on the server and wait for it to finish. My code is:
var process = new Process();
process.StartInfo.FileName = batchFilePath;
process.StartInfo.Arguments = "-0";
process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
process.Start();
process.WaitForExit();
and in the batch is simply put "pause".
The problem is that is don't see any window open and the thread is stuck and wait for the batch to finish.Only when I close the process by the windows task manager the program continues. The problem happens also if I put in the batch "cmd". How can I see the window? I want to make sure that the batch is running correctly.
This is a batch file running on the server? And you are not logged into the server, but into a web client?
You won't be able to see the console window from a web client, because it's running on a different machine.
If you are logged into the server, but still aren't seeing the window, you could try researching and experimenting with the ProcessStartInfo properties CreateNoWindow or UseShellExecute.
You might also want to look into RedirectStandardInput and RedirectStandardOutput if you need to see (or inspect programmatically) what the process writes to the console window.

Capturing Plink output in C#

I am trying to use Plink to access information on a machine. I followed this tutorial:
http://www.mindfiresolutions.com/Creating-a-SSH-connection-using-plink-PuTTY-via-C-application-1760.ph
So far I am only using my program to just open up Plink, and I will be adding in the login information and such once I can at least get Plink to be openable in my program. I have this based on the tutorial:
ProcessStartInfo psi = new ProcessStartInfo(#"C:\Windows\System32\cmd");
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
Process process = Process.Start(psi);
Thread.Sleep(3000);
string cmdForTunnel = "plink";
process.StandardInput.WriteLine(cmdForTunnel);
process.WaitForExit();
Thread.Sleep(10000);
//DoBusinessLogic();
process.StandardInput.WriteLine("logout");
Thread.Sleep(10000);
if (process.HasExited)
{
process.Close();
process.Dispose();
}
But nothing is displayed, which bothers me. The command plink is supposed to display the help information on how to use the program (I will be replacing the command with something more useful later), but the command prompt remains empty. I also experimented by replacing plink with ipconfig, which also displayed nothing.
I know how to open up cmd myself and type in plink to access it. I want to replicate this action in my program.
You have many faults in your code:
You are redirecting an output, and you are not reading/processing/printing it (that's why "nothing is displayed")
Running plink by "typing" plink to cmd.exe is insane. You can run plink directly, avoiding cmd.exe completely (and even if you needed to use the cmd.exe, you should pass plink.exe to it on a command-line: /c path\plink.exe). And no, running it directly would not cause Plink to close instantly.
Calling WaitForExit() without reading the redirected output will deadlock your code once an output buffer fills. See Remarks section for ProcessStartInfo.RedirectStandardOutput. Alternatively, use process.StandardOutput.ReadToEnd() (it's like WaitForExit, but also reads the output). It's actually what the MSDN recommends in the previous link.
If you are going to execute one command only, using Plink, it's also better to pass the command on Plink command-line, rather than "typing" it to its (redirected) input:
plink.exe -ssh user#host command
See also answer to Testing using Plink.exe to connect to SSH in C#

Calling powercfg /requests from c# gives wrong values

So I have a chunk of code to call powercfg with the /requests option and get the result back from stdout.
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "powercfg";
p.StartInfo.Arguments = "/requests";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
However when I run this code I get entirely different output than when I run the same command on the command line.
In the case of the code version I only get a load of "[DRIVER] ?" values back, but on the command line I get usually 2 or 3 properly formed responses.
I've run my code from the same command prompt window as the same user with the same environment, still no joy.
Any ideas ?
So the actual reason was that my application needed to be compiled for "Any CPU". Setting it to x86 or x64 caused issues with it loading the correct version of one of the dependent libraries.
It may have something to do with the user context your application is running in, for example if you run your app as an administrator Process.Start will attempt to start the process in the same context.

How to Connect command prompt and Visual Studio 2008?

I am new to C# and I am creating a UI for iperf(windows).
Since I could not obtain the source code for the windows version, I have to try a different method.
My aim is to create a UI which will re-direct the commands to command prompt and get the output and display it back in Visual Studio.
How do I achieve this?
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "your command here";
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Now output string variable holds result of command execution.
More details here
I suggest you check out the Process class. It will allow you to start a new process and redirect the output and error streams.
EDIT:
After reading again it is not clear why you would want to redirect back to Visual Studio. I initially read this as you want to write a UI that will send commands and display the output using Visual Studio, not actually displaying in Visual Studio.

C# .NET Process.Start() returning null when running shortcuts

Alright, I've figured out my issue. I am using some software to remotely start programs on local computers. In doing so, I send a path across the network of a program that I want that machine to start. It uses Process.Start and stores the executing path. I then, later, resend that path and tell it close the Process that was associated with this path.
Process newProcess = Process.Start(startPath);
_runningProcesses.Add(new MCProcess(startPath, new Process);
Sometimes, I will use this to call a shortcut, which I use because I want to pass some command link arguments along with.
I've used this to call .exe and .lnk (shortcut extension) and it runs the programs just fine.
However, when passing in the path to a shortcut, the process that it returns is null! Therefor, when I send the path back to close the program, the process is null and it can't close the program.
Any solutions?
You don't need shortcut to pass arguments to the program, just do following:
Process process = new Process();
process.StartInfo.FileName = "\"C:\\my.exe\"";
process.StartInfo.Arguments = "arg1 arg2 arg3";
//...
process.Start();
In command line it would look like C:\my.exe arg1 arg2 arg3
just take the target of the shortcut if its necessary to use the shortcut.
Get target of shortcut folder

Categories

Resources