views:

192

answers:

2

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.

+1  A: 

try using FileMode.OpenOrCreate | FileMode.Append in File.Open method

Adeel
+1  A: 

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.

Moron
thanks, Moron, thanks. :D
smwikipedia
I added FileShare.None but still Process B could access the file. But if I run Program B independently while Program A is running, access denied exeption is thrown. If I let Process B started by Process A, there's no exception and Process B could still write to the file. Is it because Process B is started by A and inherited the file from A?
smwikipedia
You probably exited Process A even before B got to open the file (and so B could open). Try putting a Console.Read or something in Process A after you start B and see what happens.
Moron