I have a c# windows service application that is crashing without throwing an exception when processing certain files using a third-party .dll. What I decided to do was create a new console application which replicates a small portion of the windows service code, particularly the part the causes the service to crash. What I want to do is call the new .exe program from the windows service, and if it crashes, I throw an exception myself.
So, I need to call this .exe program (not in the background as I can't allow the windows service to continue until I know the file to be processed is safe), and then determine if it exited successfully or not. How do I go about doing this? The examples I've seen run the .exe in a background process which is not what I want.
Thanks.
Look at this SO answer how to run console application from windows service. Just add WaitForExit, like this :
ProcessStartInfo info = new ProcessStartInfo(#"c:\myprogram.exe");
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.CreateNoWindow = true;
info.ErrorDialog = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(info);
process.WaitForExit();
In console application you can set exit code if you exit with Environment.Exit(statusCode) or return int value from main function of console applicaiton. Or you can write to output and then in your service examine exit code (process.ExitCode) or output stream so you can determine is process was exited successfully.
Related
So here's my problem:
Python scripts launched from C# via the Process class require the -i switch to be passed to python.exe or else they don't send any output when I redirect the StandardXxx streams
I want to bundle my Python program with py2exe (or another similar setup, if one meets my needs)
py2exe does not seem to let me pass the -i switch in any obvious way, but it's giving my the same issue as running python.exe - it doesn't output anything when launched by my C# program. So I need a way to force it into a similar mode so I can actually receive and send messages over stdin/stdout. I found some similar problems when it's built with "windows=['my_script']" but I built it with "console=['my_script']", so those fixes didn't help, and I don't need an actual interactive mode (i.e. the REPL), but for some reason the -i switch fixes the console IO issues.
This is the code I'm using to launch it:
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.FileName = "py2exe_program.exe";
Process p = Process.Start(psi);
// program hangs here because ready message is never printed
p.StandardOutput.ReadLine(); // Consume ready message
The executable works as expected when launched externally, and the above code works when I launch the Python script via "python.exe -i my_script.py" but it runs into the same problem without the -i switch.
How do I get it to behave as expected?
I need to run a console application for which I do not have any source code (I only have the binaries) from my WCF REST web service. Once my service is up and running (localhost, debug), I enter the following code :
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = strCommand;
p.StartInfo.Arguments = strCommandParameters;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
My .exe file is found but nothing happens. I put a breakpoint after this code and it stops there so the code is executed. Whatever happens regarding the command parameters, the console application is supposed to produce at least a log.txt file in its directory, but it does not. Any ideas?
EDIT: It was working...the only difference is the log.txt file was generated in the debug directory of the running web application instead of the directory of the console application. So the relative path of the output file is relative to the server web application.
I´d guess you are hosting the WCF Service in IIS and the console application is started using the AppPool Credentials not having enough privileges. You may try to use the ProcessMonitor to monitor the Service/ConsoleApp and check for access denied messages
SHORT VERSION
How do you figure out which DLL is failing to load (and potentially why) when a process exits with error code -1073741502?
LONG VERSION
I'm trying to write a pretxnchangegroup hook for Mercurial, and as a part of that hook I need to get the output of running the command:
hg log
The code that I'm using to start and run the hg.exe process is as follows:
string Command = "log";
Process p = new Process();
ProcessStartInfo psi = p.StartInfo;
p.StartInfo.FileName = #"C:\Program Files (x86)\Mercurial\hg.exe";
psi.CreateNoWindow = true;
psi.LoadUserProfile = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.WorkingDirectory = Environment.CurrentDirectory;
p.StartInfo.Arguments = Command;
// Pass-through environment variables
psi.UserName = Properties.Settings.Default.HG_User;
psi.Domain = Properties.Settings.Default.HG_Domain;
psi.Password = new System.Security.SecureString();
foreach (char c in Properties.Settings.Default.HG_Pass)
{
psi.Password.AppendChar(c);
}
p.Start();
p.WaitForExit();
The problem is that the process keeps exiting with error code -1073741502, without outputting anything on Standard Output or Standard Error. After some research online, I discovered that this error code has something to do with the application failing to initialize properly (couldn't find DLL's, maybe?), but I have no idea how to go about figuring out how to fix it.
Keep in mind that this hook is being called for when I'm pushing to the repository over the web (so, IIS is calling the Mercurial CGI via Python, which has this program configured as a hook).
In a totally different web application, I'm able to run HG commands just fine, and I'm also able to run this by doing
runas /user:<same account as in the code> /noprofile cmd.exe and then manually typing in the hg command line.
Also, if I set UseShellExecute = true, then it executes just fine, but then I can't get the Standard Output. I'm really tempted to just make a web service call to the web app which is able to execute this command successfully, but that'd be a really ugly solution.
Any ideas why this thing isn't executing?
I was able to resolve this by disabling UAC so it sounds like a permissions problem even though I do not know the exact details.
I am using the following code to run a batch file from C#. The following code is part of my windows service. This code works perfectly fine in Windows XP but when I deploy my windows service to Windows server 2003 OS it returns exit code 1 (failure). Does someone know what I am missing? Do I need to give some special permission to the windows service? The service is installed as a Local System service.
ProcessStartInfo psi = new ProcessStartInfo();
//specify the name and arguments to pass to the command prompt
psi.FileName = ConfigurationManager.AppSettings["BatchFilePath"];
psi.Arguments = fileName;
//Create new process and set the starting information
Process p = new Process();
p.StartInfo = psi;
//Set this so that you can tell when the process has completed
p.EnableRaisingEvents = true;
p.Start();
//wait until the process has completed
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
}
//check to see what the exit code was
if (p.ExitCode != 0)
{
logger.Write("Exit Code" + p.ExitCode);
}
My next set would be to try setting the service to run as the user you're logged in as when it works. That way you'll know whether it is something specific to the Network Service account that's stopping it working
I have to run a console application from my Windows Application. The console application I want to run is an Embedded Resource in my application, and I am calling it like this:
// Run the updater and grab its output
Process Updater = new Process();
Updater.StartInfo.FileName = "C:\\tmp\\tmp.exe";
Updater.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Updater.StartInfo.UseShellExecute = false;
Updater.StartInfo.RedirectStandardOutput = true;
Updater.Start();
string UpdaterOutput = Updater.StandardOutput.ReadToEnd();
Updater.WaitForExit();
It extracts fine, and it runs fine, and it also grabs its output completely fine... but I can still see the console Window popping open quickly as it's run. I know the console pop up is from this application because the console title is C:\tmp\tmp.exe. Is there any completely fail proof way to hide the console application? I thought using ProcessWindowStyle.Hidden would do it but apparently not.
Thanks.
Set the ProcessStartInfo.CreateNoWindow property to true