Blue screen when using Ping - c#

I'm running into the bug where it BSODon ending debugging in the middle of a ping.
I have a few ways to disable it in my (wpf) application (where I ping continuously), but sometimes I forget to do so and BSOD.
I'd like to get around that say by changing a global AllowRealPinging variable and sleeping for 2 seconds in a callback before exiting the debugger so I don't BSOD.

This is a known bug in Windows 7, you'll get a BSOD with bug-check code 0x76, PROCESS_HAS_LOCKED_PAGES in tcpip.sys when you terminate the process. The most relevant feedback article is here. Also covered in this SO question. No great answers there, the only known workaround is to fallback to a .NET version earlier than 4.0, it uses another winapi function that doesn't trigger the driver bug.
Avoiding pinging while you debug is certainly the best way to avoid this problem. Your desired approach is not going to work, your program is entirely frozen when it hits a breakpoint, kaboom when you stop debugging.
The simplest way is to just not starting pinging in the first place in the specific case of having a debugger attached. Use the System.Diagnostic.Debugger.IsAttached property to detect this in your code.

This is a good way around:
private void GetPing(){
Dictionary<string, string> tempDictionary = this.tempDictionary; //Some adresses you want to test
StringBuilder proxy = new StringBuilder();
string roundTripTest = "";
string location;
int count = 0; //Count is mainly there in case you don't get anything
Process process = new Process{
StartInfo = new ProcessStartInfo{
FileName = "ping.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
}
};
for (int i = 0; i < tempDictionary.Count; i++){
proxy.Append(tempDictionary.Keys.ElementAt(i));
process.StartInfo.Arguments = proxy.ToString();
do{
try{
roundTripTest = RoundTripCheck(process);
}
catch (Exception ex){
count++;
}
if (roundTripTest == null){
count++;
}
if (count == 10 || roundTripTest.Trim().Equals("")){
roundTripTest = "Server Unavailable";
}
} while (roundTripTest == null || roundTripTest.Equals(" ") || roundTripTest.Equals(""));
}
process.Dispose();
}
RoundTripCheck method, where the magic happens:
private string RoundTripCheck(Process p){
StringBuilder result = new StringBuilder();
string returned = "";
p.Start();
while (!p.StandardOutput.EndOfStream){
result.Append(p.StandardOutput.ReadLine());
if (result.ToString().Contains("Average")){
returned = result.ToString().Substring(result.ToString().IndexOf("Average ="))
.Replace("Average =", "").Trim().Replace("ms", "").ToString();
break;
}
result.Clear();
}
return returned;
}
I had the same problem, this solves it!

Related

"The process cannot access the file because it is being used by another process." with SystemReader

I have no coding experience but have been trying to fix a broken program many years ago. I've been fumbling through fixing things but have stumbled upon a piece that I can't fix. From what I've gathered you get Alexa to append a Dropbox file and the program reads that file looking for the change and, depending on what it is, executes a certain command based on a customizable list in an XML document.
I've gotten this to work about five times in the hundred of attempts I've done, every other time it will crash and Visual Studio gives me: "System.IO.IOException: 'The process cannot access the file 'C:\Users\\"User"\Dropbox\controlcomputer\controlfile.txt' because it is being used by another process.'"
This is the file that Dropbox appends and this only happens when I append the file, otherwise, the program works fine and I can navigate it.
I believe this is the code that handles this as this is the only mention of StreamReader in all of the code:
public static void launchTaskControlFile(string path)
{
int num = 0;
StreamReader streamReader = new StreamReader(path);
string str = "";
while (true)
{
string str1 = streamReader.ReadLine();
string str2 = str1;
if (str1 == null)
{
break;
}
str = str2.TrimStart(new char[] { '#' });
num++;
}
streamReader.Close();
if (str.Contains("Google"))
{
MainWindow.googleSearch(str);
}
else if (str.Contains("LockDown") && Settings.Default.lockdownEnabled)
{
MainWindow.executeLock();
}
else if (str.Contains("Shutdown") && Settings.Default.shutdownEnabled)
{
MainWindow.executeShutdown();
}
else if (str.Contains("Restart") && Settings.Default.restartEnabled)
{
MainWindow.executeRestart();
}
else if (!str.Contains("Password"))
{
MainWindow.launchApplication(str);
}
else
{
SendKeys.SendWait(" ");
Thread.Sleep(500);
string str3 = "potato";
for (int i = 0; i < str3.Length; i++)
{
SendKeys.SendWait(str3[i].ToString());
}
}
Console.ReadLine();
}
I've searched online but have no idea how I could apply anything I've found to this. Once again before working on this I have no coding experience so act like you're talking to a toddler.
Sorry if anything I added here is unnecessary I'm just trying to be thorough. Any help would be appreciated.
I set up a try delay pattern like Adriano Repetti said and it seems to be working, however doing that flat out would only cause it to not crash so I had to add a loop around it and set the loop to stop when a variable hit 1, which happened whenever any command types are triggered. This takes it out of the loop and sets the integer back to 0, triggering the loop again. That seems to be working now.

How to embed interactive python process in C# WinForm

Question
I am trying to start Python as a System.Diagnostics.Process and redirect its standard output, input and error to a RichTextBox on a Windows form, so that I can have a python REPL on my form.
The process starts correctly (Start() returns true) however no output or error data is ever sent from the process:
If I try to Read from the StandardOutput or StandardError the read just hangs.
If I instead subscribe to OutputDataReceived and ErrorDataReceived they never fire.
started with ProcessStartInfo("Python.exe")
I only see output from python once I kill it by sending Ctrl + C (sent after pressing Enter at the end of the line asd, hence the 3rd line).
To clarify, I want to see "2" sent from python (either from Reading the StandardOutput stream, or in the data event), after I pressed enter after entering "1 + 1".
Why is no data being sent to the Standard outputs and no events raised whilst python is executing? Is it possible to have this work as I want it (so that response from python is given immediately).
Additional
If instead I start cmd.exe then everything is fine and I can use the form as I would a regular command prompt. So to some extent my application is working.
However if I try to start python using this form, then it hangs until I kill the process by sending Ctrl + C as before:
started with ProcessStartInfo("cmd.exe")
Evidently the standard input is getting to python (since the line number reported by the python error message changes depending on how many lines before it)
I am using:
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)] on win32
Again:
Why does python not send any data to standard out or cause any events to be raised until it dies? How can I make it?
Code
Some of this follows the pattern of www.codeproject.com/Articles/335909/Embedding-a-Console-in-a-C-Application
Setup
var processStartInfo = new ProcessStartInfo("python.exe");
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.CreateNoWindow = true;
process = new Process();
process.StartInfo = processStartInfo;
bool processStarted = process.Start();
outputReader = process.StandardOutput;
errorReader = process.StandardError;
inputWriter = process.StandardInput;
// start reading from standard output
outputWatchWorker.WorkerSupportsCancellation = true;
outputWatchWorker.DoWork += (o, e) =>
{
while (!outputWatchWorker.CancellationPending)
{
int nChars = 0;
string str;
char[] buffer = new char[1024];
nChars = outputReader.Read(buffer, 0, buffer.Length);
if (nChars > 0)
{
str = new string(buffer, 0, nChars);
Invoke((MethodInvoker)(() =>
{
WriteOutput(str, Color.Black);
}));
}
}
};
outputWatchWorker.RunWorkerAsync();
// I've removed an almost identical block of code for errorWatchWorker to read from the error stream
KeyDown event of RichTextBox
// some extra code here I haven't included to prevent deletion of stuff printed from standard out
// just checks the cursor position and then suppresses the event if certain keys are pressed
// I can provide if it will help
if (e.KeyCode == Keys.Return)
{
string input = textConsole.Text.Substring(inputStart, textConsole.SelectionStart - inputStart);
lastInput = input;
inputStart = textConsole.SelectionStart + 1; // inluding the new line
inputWriter.WriteLine(input);
inputWriter.Flush();
if (string.IsNullOrWhiteSpace(input)) e.SuppressKeyPress = true;
}
WriteOutput
public void WriteOutput(string output, Color color)
{
if (string.IsNullOrEmpty(lastInput) == false &&
(output == lastInput || output.Replace("\r\n", "") == lastInput))
return;
Invoke((Action)(() =>
{
// Write the output.
textConsole.SelectionColor = color;
textConsole.AppendText(output);
inputStart = textConsole.SelectionStart;
}));
}
The click listener of the "Ctrl + C" button to send Ctrl+C
just does
inputWriter.WriteLine("\x3");
based on this question How do I send ctrl+c to a process in c#?

How to redirect output from the NASM command line assembler in C#

Brief Summary
I am creating a lightweight IDE for NASM development in C# (I know kind of an irony). Kinda of like Notepad++ but simpler but with features that make it more than source editor. Since Notepad++ is really just a fancy source editor. I have already implemented features like Project creation (using a project format similar to how Visual Studio organizes projects). Project extension .nasmproj. I am also in the works of hosting it in an open-source place (Codeplex). Although the program is far from finish, and definitely cannot be used in a production environment without proper protection and equipment. In addition, I am working alone with it at this moment, more like a spare time project since I just finished my last Summer final taking Calculus I.
Problem
Right now I am facing a problem, I can build the project but no output from NASM is being fed into the IDE. I have succesfully built a project, and I was able to produce object files. I even tried producing a syntax error to see if I finally see something come up but none and I check the bin folder of the test project I created and I see no object file creating. So definitely NASM is doing its magic. Is it because NASM doesn't want me to see its output. Is there a solution? Any advice would be great. Here is the code which I think is giving Trouble.
Things to Note
I have already checked if events have been invoked. An yes they have but they return empty strings
I have also checked error data and same effect.
Code
public static bool Build(string arguments, out Process nasmP)
{
try
{
ProcessStartInfo nasm = new ProcessStartInfo("nasm", arguments);
nasm.CreateNoWindow = true;
nasm.RedirectStandardError = true;
nasm.RedirectStandardInput = true;
nasm.RedirectStandardOutput = true;
nasm.UseShellExecute = false;
nasmP = new Process();
nasmP.EnableRaisingEvents = true;
nasmP.StartInfo = nasm;
bool predicate = nasmP.Start();
nasmP.BeginOutputReadLine();
return true;
}
catch
{
nasmP = null;
return false;
}
}
//Hasn't been tested nor used
public static bool Clean(string binPath)
{
if (binPath == null || !Directory.Exists(binPath))
{
throw new ArgumentException("Either path is null or it does not exist!");
}
else
{
try
{
DirectoryInfo binInfo = new DirectoryInfo(binPath);
FileInfo[] filesInfo = binInfo.GetFiles();
for (int index = 0; index < filesInfo.Length; index++)
{
try
{
filesInfo[index].Delete();
filesInfo[index] = null;
}
catch
{
break;
}
}
GC.Collect();
return true;
}
catch
{
return false;
}
}
}
}
using (BuildDialog dlg = new BuildDialog(currentSolution))
{
DialogResult result = dlg.ShowDialog();
dlg.onOutputRecieved += new BuildDialog.OnOutputRecievedHandler(delegate(Process _sender, string output)
{
if (result == System.Windows.Forms.DialogResult.OK)
{
outputWindow.Invoke(new InvokeDelegate(delegate(string o)
{
Console.WriteLine("Data:" + o);
outputWindow.Text = o;
}), output);
}
});
}
Edits
I have tried doing synchronously instead of asynchronously but still the same result (and empty string "" is returned) actually by debugging the stream is already at the end. So looks like nothing has been written into the stream.
This is what I tried:
string readToEnd = nasmP.StandardOutput.ReadToEnd();
nasmP.WaitForExit();
Console.WriteLine(readToEnd);
And another interesting thing I have tried was I copied the arguments from the debugger and pasted it in the command line shell and I can see NASM compiling and giving the error that I wanted to see all along. So definitely not a NASM problem. Could it be a problem with my code or the .Net framework.
Here is a nice snapshot of the shell window (although not technically proof; this is what the output should look like in my IDE):
Alan made a very good point, check the sub processes or threads. Is sub process and thread synonymous? But here is the problem. Almost all the properties except a select few and output/error streams are throwing an invalid operation. Here is the debugger information as an image (I wish Visual Studio would allow you to copy the entire information in click):
Okay I finally was able to do it. I just found this control that redirect output from a process and I just looked at the source code of it and got what I needed to do. Here is the the modified code:
public static bool Build(string command, out StringBuilder buildOutput)
{
try
{
buildOutput = new StringBuilder();
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
startInfo.Arguments = "/C " + " nasm " + command;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process p = Process.Start(startInfo);
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();
if (output.Length != 0)
buildOutput.Append(output);
else if (error.Length != 0)
buildOutput.Append(error);
else
buildOutput.Append("\n");
return true;
}
catch
{
buildOutput = null;
return false;
}
}
Here is how the output is formatted like:
I also wanted to thank Alan for helping me debug my code, although he didn't physically had my code. But he really was helpful and I thank him for it.

how to find out the path of the program using c#

I found a snippet of code explaining how to use System.Diagnostics.Process.Start to run an external program in C#. The snippet shows running cmd.exe, which is in the path.
Let's assume that there is some external program (Beyond Compare for example). I don't know if it is installed on the PC. How can I check if this program is installed using C#? If the program is installed, I would like to find the path so that I can launch it.
I found this question, which directed me to this this article.
I've modified the source for readability, and to solve your problem specifically (note that I've guessed the description and executable name of Beyond Compare.)
You can call it like this, from your main:
string path = FindAppPath("Beyond Compare");
if (path == null)
{
Console.WriteLine("Failed to find program path.");
return;
}
path += "BeyondCompare.exe";
if (File.Exists(path))
{
Process beyondCompare = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = path + "BeyondCompare.exe",
Arguments = string.Empty // You may need to specify args.
}
};
beyondCompare.Start();
}
The source for FindAppPath follows:
static string FindAppPath(string appName)
{
// If you don't use contracts, check this and throw ArgumentException
Contract.Requires(!string.IsNullOrEmpty(appName));
const string keyPath =
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath))
{
var installed =
(from skName in key.GetSubKeyNames()
let subkey = key.OpenSubKey(skName)
select new
{
name = subkey.GetValue("DisplayName") as string,
path = subkey.GetValue("InstallLocation") as string
}).ToList();
var desired = installed.FindAll(
program => program.name != null &&
program.name.Contains(appName) &&
!String.IsNullOrEmpty(program.path));
return (desired.Count > 0) ? desired[0].path : null;
}
}
Keep in mind that this method returns the first matching path, so don't feed it an appName argument that's too generic (eg. "Microsoft") or you probably won't get what you're looking for.
Well, if you're trying to see if a program exists where you're looking for it (like BeyondCompare.exe), you can just use a call to:
System.IO.File.Exists("path_to_program.exe");
If it returns true, then you know your program exists and you can run it with your process runner code. If it returns false, then you know it's not there and you shouldn't launch your process.
If I'm misunderstanding your question, please let me know and I'll update my answer accordingly.
Thanks. Hope this helps!
Simple logic to do for this.
string filepath = "c:\windows\test.exe";
bool bOk = false;
try
{
bOk = System.IO.File.Exists(filepath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (!bOk)
{
Console.WriteLine("Error: Invalid Path");
}
else
{
Process p = new Process();
p.StartInfo.FileName = filepath;
p.StartInfo.Arguments = "/c dir *.cs";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);
}
Are you sure you don't need to make that check. Simply start the program without path (only the filename) and set ProcessStartInfo.UseShellExecute = true.
Windows will look for the app in its list of installed app. If it doesn't find it, Process.Start()will fail. The interesting thing is that you never had to care about where the app is stored.

Capture output of process synchronously (i.e. "when it happens")

I am trying to start a process and capture the output, have come a far way, but am not quite at the solution I'd want.
Specifically, I am trying to reset the IIS on my development machine from a small utility application that I am writing. I have come to the conclusion, by experimenting, that the safe way to do this is by running iisreset.exe in a child process.
If you run iisreset.exe on a command prompt, you get feedback during the process. Running iisreset takes several seconds, and several lines of feedback is generated, with pauses in between.
I'd like to capture this feedback and present it in my Windows Forms application (in a ListBox), and I have succeeded with that. My remaining concern is that I dont get it until the child process finishes. I'd like to get the output from the child process, line by line, immediately when the lines are created.
I have tried to do my homework, reading/testing things from e.g. these:
How to spawn a process and capture its STDOUT in .NET?
Capturing console output from a .NET application (C#)
http://www.aspcode.net/ProcessStart-and-redirect-standard-output.aspx
and several more with similar content. Most (all?) get the output asynchronously (e.g. with Process.ReadToEnd()). I want the output synchonously, which acording to the MSDN documentation involves establishing an event handler etc and I've tried that. It works, but the event handler does not get called until the process exits. I get the output from iisreset.exe, but not until it has finished.
To rule out the possibility that this has something to do with iisreset.exe in particular, I wrote a small console application that generates some output, pausing in between:
namespace OutputGenerator
{
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("OutputGenerator starting and pausing for 10 seconds..");
System.Threading.Thread.Sleep(10000);
System.Console.WriteLine("Pausing for another 10 seconds..");
System.Threading.Thread.Sleep(10000);
System.Console.WriteLine("Exiting!");
}
}
}
Testing with this it turns out that I get captured data diretly when I want. So, to some extent it seems that the way iisreset.exe outputs the data come into play here.
Here is the code of the program (a Windows Forms application) that does the capture:
using System;
using System.Windows.Forms;
using System.Diagnostics;
namespace OutputCapturer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnRun_Click(object sender, EventArgs e)
{
// Running this will show all output after the process has exited
//String path = #"C:\Windows\system32\iisreset.exe";
// Running this will show all output "when it happens"
String path = #"C:\OutputGenerator.exe";
var p = new Process();
p.StartInfo.FileName = path;
p.StartInfo.UseShellExecute = false; // ShellExecute = true not allowed when output is redirected..
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += OutputDataReceived;
p.Start();
p.BeginOutputReadLine();
}
private delegate void OutputDataToTextboxDelegate(String s);
void OutputDataToTextbox(String s)
{
tbxOutput.Text += s + Environment.NewLine;
tbxOutput.Refresh();
}
private void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && e.Data.ToString() != "")
{
// Must run the update of the textbox in the same thread that created it..
tbxOutput.Invoke(
new OutputDataToTextboxDelegate(OutputDataToTextbox),
DateTime.Now.ToString() + ": " + e.Data.ToString()
);
}
}
}
}
Thinking it was an EOL-encoding problem (the output of iisreset.exe apearing as one line to my app)), I ran a debug session. Nope. The event handler for StandardOutput gets called several times (one time for each output line from iisreset.exe), buth these calls come in one burst after the process exits.
I would LOVE if I could get the output from iisreset.exe "when it happens" so that I can show it as a progress indication.
I've seen one other thread with the same/similar problem, Asynchronous capture from a process output not working properly , but w/o a solution.
I'm sort of stumped.
To do autoflushing of printfs / stdouts
C equivalent of autoflush (flush stdout after each write)?
This saved my ass...
It seems that sixlettervariables is correct, and that this has something to do with iisreset.exe isn't flushing it's buffers for each line. (I still wonder what makes it work on a plain command line - i.e. what does cmd.exe do?)
Anyhow.. I tried what apacay suggested, and wrote this:
private void btnRun_Click(object sender, EventArgs e)
{
// Running this will show the output after the process has finished
//String path = #"C:\Windows\system32\iisreset.exe";
// Running this will show all output "when it happens"
String path = #"C:\OutputGenerator.exe";
var p = new Process();
p.StartInfo.FileName = path;
p.StartInfo.UseShellExecute = false; // ShellExecute = true not allowed when output is redirected..
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
StreamReader sr = p.StandardOutput;
while (!sr.EndOfStream)
{
String s = sr.ReadLine();
if (s != "")
{
tbxOutput.Text += DateTime.Now.ToString() + ": " + s + Environment.NewLine;
}
tbxOutput.Refresh();
}
}
Notice that I am timestamping when I get each line. For my OutputGenerator I get this:
2011-07-06 17:49:11: OutputGenerator starting and pausing for 10 seconds..
2011-07-06 17:49:21: Pausing for another 10 seconds..
2011-07-06 17:49:31: Exiting!
And for iisreset.exe I get this:
2011-07-06 17:57:11: Attempting stop...
2011-07-06 17:57:11: Internet services successfully stopped
2011-07-06 17:57:11: Attempting start...
2011-07-06 17:57:11: Internet services successfully restarted
Running iisreset.exe on the command line, those lines come with pauses in between, over a span of perhaps 10 seconds.
The case seems more or less closed now. Not that I am all that satisfied, but I'm at roads end it seems. I'll reluctantly live with it..
To summarise: In the general case, it is quite possible to capture output synchronously with when it is generated. This thread presents code for two ways to do that - by establishing an event handler, and by "polling" the stream. In my specific case there is something with how iisreset.exe generates output that prevents this.
Thanks to those who participated and contributed!
Well.... you could kick it old-school. Output can be redirected to the input of another program using old-school DOS commands (foo.exe | bar.exe). Write a program that reads from standard in, and you'll get it every time the stream flushes.
Edit
You could also redirect the ouput to a named pipe and read from that. That would also be "as it happens".
Well, I tried a helper class that I know works: http://csharptest.net/browse/src/Library/Processes/ProcessRunner.cs
ProcessRunner runner = new ProcessRunner("iisreset.exe");
runner.OutputReceived += OutputDataReceived;
runner.Start("/RESTART", "/STATUS");
However, this still doesn't solve the problem with this specific executable. It seems that iisreset was written in such a way that this is not possible. Even running the following from the command line:
iisreset.exe /RESTART /STATUS > temp.txt
Still nothing is written to the text file 'temp.txt' until after all services have been restarted.
As for your example code, I would recommend reading a post I wrote some time ago: How to use System.Diagnostics.Process correctly. Specifically you are not reading the std::err stream or redirecting and closing the std::in stream. This can cause very undesirable results in your program. You can look at the example wrapper class linked above for how to do it with the output events, or if you want to directly read the streams you need to use two of your own threads.
static void Main()
{
ProcessStartInfo psi = new ProcessStartInfo(#"C:\Windows\system32\iisreset.exe", "/RESTART /STATUS");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
ManualResetEvent output_complete = new ManualResetEvent(false);
ManualResetEvent error_complete = new ManualResetEvent(false);
Process p = Process.Start(psi);
new ReadOutput(p.StandardOutput, output_complete);
new ReadOutput(p.StandardError, error_complete);
p.StandardInput.Close();
p.WaitForExit();
output_complete.WaitOne();
error_complete.WaitOne();
}
private class ReadOutput
{
private StreamReader _reader;
private ManualResetEvent _complete;
public ReadOutput(StreamReader reader, ManualResetEvent complete)
{
_reader = reader;
_complete = complete;
Thread t = new Thread(new ThreadStart(ReadAll));
t.Start();
}
void ReadAll()
{
int ch;
while(-1 != (ch = _reader.Read()))
{
Console.Write((char) ch);
}
_complete.Set();
}
}
I wrote this just to see if anything was coming through. Still got nothing until the end, so I think your just SOL on getting asynchronous output from iisreset.
I've had that problem and had to solve it when my logs where too long to read in a single readtoend.
This is what I've done to solve it. It's been doing Ok so far.
myProcess.StartInfo.FileName = path;
myProcess.StartInfo.Arguments = args;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.ErrorDialog = false;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.StartInfo.RedirectStandardInput = (stdIn != null);
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.Start();
int index;
OpenLogFile(myLog); //LOGGGGGGGGGGGGG
if (myProcess.StartInfo.RedirectStandardInput)
{
StreamWriter sw = myProcess.StandardInput;
sw.Write(stdIn + Convert.ToChar(26));
}
StreamReader sr = myProcess.StandardOutput;
/*stdOut = new ArrayLi
*/
while (!sr.EndOfStream)
{ //LOGGGGGGGGGGGGG
Log(sr.ReadLine(), true);
}
Here's OpenLogFile
private void OpenLogFile(string fileName)
{
if (file == StreamWriter.Null)
{
file = new StreamWriter(fileName, true);
file.AutoFlush = true;
}
}
Of course that Log is a function that does something elsewhere. But the solution to you question lies here:
while (!sr.EndOfStream)
{ //LOGGGGGGGGGGGGG
Log(sr.ReadLine(), true);
}
while stream reader is still reading, you can be writing it down as the log comes out.
For my specific situation, the solution is what Mr Moses suggested in a comment above, i.e. run iisreset /stop followed by iisreset /start.
I need a proper answer, rather than a comment, in order to mark it as my "accepted answer", so this answer is more of administrativa than a new contribution. The cred should go to Mr Moses.. :-)

Categories

Resources