views:

35

answers:

0

I am trying to create a class that can display debug string in a separate console than the program that uses it, either a form or another console. The idea is to have your program run normally, but have all the debug messages in another console. Since a process can only have one console at a time, I start my debug console in another process and send strings to it via NamedPipe.

Now my class is pretty basic for now, but it should work. However, when the client side tries to connect to the server's pipe, I get 'UnauthorizedAccessException: Access to the path is denied.'. Both the client and server run on the same machine and under the same user. I really don't get the security side of .net so I need some help. I spend hours on the web, where I found different solutions, but none of them worked. I use .net 4 under XP but it should also work with Vista/7

Here his my class:

public class SideConsole
{
    NamedPipeClientStream pipeStream;
    StreamWriter sw;

    public SideConsole() : this("Console1") { }
    public SideConsole(string consoleName)
    {
        #if DEBUG

        string fileName = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
        ProcessStartInfo startInfo = new ProcessStartInfo(fileName);
        startInfo.Arguments = "\"" + consoleName + "\"";

        Process.Start(startInfo);

        pipeStream = new NamedPipeClientStream(consoleName);
        pipeStream.Connect(5000); // Throws UnauthorizedAccessException

        sw = new StreamWriter(pipeStream);
        sw.AutoFlush = true;
        #endif
    }

    ~SideConsole()
    {
        if(sw != null)
            sw.Dispose();

        if(pipeStream != null)
            pipeStream.Dispose();
    }

    public void WriteLine(object value) { WriteLine(value.ToString()); }
    public void WriteLine(string value)
    {
        #if DEBUG
        sw.WriteLine(value);
        #endif
    }

    public static void Main(string[] args)
    {
        #if DEBUG

        if (args.Length == 1 )
        {
            using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(args[0])
            {
                Console.WriteLine("Waiting for client connection ...");
                pipeStream.WaitForConnection();
                Console.Clear();

                Console.WriteLine("**************************************");
                Console.WriteLine("*                                    *");
                Console.WriteLine("*        Side console started        *");
                Console.WriteLine("*                                    *");
                Console.WriteLine("**************************************");
                Console.WriteLine();

                Console.Title = args[0];

                try
                {
                    using (StreamReader sr = new StreamReader(pipeStream))
                    {
                        string temp;
                        // We read a line from the pipe and print it
                        while ((temp = sr.ReadLine()) != null)
                        {
                                Console.WriteLine(temp);
                        }
                    }
                }
                catch (IOException)
                {
                    Console.WriteLine();
                    Console.WriteLine("Client disconnected...");
                    Console.WriteLine();
                }
            }
        }
        else
        {
            Console.WriteLine("Error in executable call.");
            Console.WriteLine("You must provide the (window title / pipe name) as the first argument.");
            Console.WriteLine("i.e.  'SideConsole.exe Console1'");
            Console.WriteLine();
        }

        Console.Write("Press any key to exit.");
        Console.Read();

        #endif
    }
}

With a reference to that class, any other project could use this as such :

SideConsole console = new SideConsole("Title");
console.WriteLine("Start of process A");
// do some work
console.WriteLine("End of process");

Thanks in advance for all your bright answers.