Reputation: 64205
I write two windows console application as below
class ProgramA
{
static void Main(string[] args)
{
FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
TextWriter old = Console.Out;
Console.SetOut(sw);
Console.WriteLine("Process A Started " + DateTime.Now.ToString());
sw.Flush();
Process p = new Process();
ProcessStartInfo pi = new ProcessStartInfo();
pi.FileName = @"D:\ProgramB.exe";
p.StartInfo = pi;
pi.UseShellExecute = true;
pi.RedirectStandardOutput = false;
bool result = p.Start();
Console.WriteLine("Process A Ended " + DateTime.Now.ToString());
sw.Flush();
}
}
And
class ProgramB
{
static void Main(string[] args)
{
try
{
FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
TextWriter old = Console.Out;
Console.SetOut(sw);
Console.WriteLine("Process B output " + DateTime.Now.ToString());
sw.Flush();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
They are totally different exe files. When I debug ProgramA step by step with F5, the result in E:\console.txt is
Process A Started 2/26/2010 13:43:59 Process A Ended 2/26/2010 13:44:03
But if I just run ProgramA with Ctrl+F5, the result in E:\console.txt is
Process B output 2/26/2010 13:48:50 Process A Ended 2/26/2010 13:48:50
I am confused. Originally, I want to have the 2 process both write to the same file. But after some reflection, I thought since Process A has taken control of the console.txt first, Process B shouldn't be able to have access to console.txt, and the result should be similar to below:
Process A Started 2/26/2010 13:43:59 Process A Ended 2/26/2010 13:44:03
with Process B throw an access denied exception. But it's not. Why? Where is the "Process A Started" message?
I change my code to the below:
class ProgramA
{
static void Main(string[] args)
{
FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
TextWriter old = Console.Out;
Console.SetOut(sw);
Console.Write("aaaaa");
Console.Write("AAAAA");
sw.Flush();
Process p = new Process();
ProcessStartInfo pi = new ProcessStartInfo();
pi.FileName = @"D:\ProgramB.exe";
p.StartInfo = pi;
pi.UseShellExecute = true;
pi.RedirectStandardOutput = false;
bool result = p.Start();
Console.Write("aaaaa");
sw.Flush();
}
And
class ProgramB
{
static void Main(string[] args)
{
try
{
FileStream fs = File.Open(@"E:\console.txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
TextWriter old = Console.Out;
Console.SetOut(sw);
Console.Write("bbb");
sw.Flush();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
And the content of console.txt is
bbbaaAAAAAaaaaa
Maybe this could explain something. I am figuring it out.
Thanks.
Upvotes: 4
Views: 471
Reputation:
Two things:
first, since you have not used FileShare.None, both exes will have access to the file, so Process B can still access the file.
second, since you have opened the file with OpenOrCreate (and nothing else), the file will be opened and writes you do will be from the start of the file. Try doing a FileStream.Seek to seek to the end of the file before writing. Opening the file in FileMode.Append won't really help (if you run them in parallel), I think, as both processes will still trample on each other.
Better yet, try doing a FileStream.Lock to ensure the two processes don't trample on each other.
Upvotes: 1
Reputation: 19228
try using FileMode.OpenOrCreate | FileMode.Append
in File.Open
method
Upvotes: 1