Patrik
Patrik

Reputation: 1346

.NET Environment.NewLine - how to setup programmatically

I would like to change the default Environment.NewLine character for my current environment.

I have one standalone application that is writing messages to a console. When the core framework works in the console environment the new line is \r\n. When I move the core framework into a Windows service the Environment.NewLine changes to "\n".

I would like to be able to change the Console to always use "\r\n" because when I redirect the output of the console to a file the output has no "windows new lines" when read from example Notepad.

I would like Console.WriteLine to use \r\n whenever I want.

EDIT:

I am redirecting Console.out:

        ConsoleOut = File.AppendText(fileName);
        ConsoleOut.AutoFlush = true;


        Console.SetOut(ConsoleOut);
        Console.SetError(ConsoleOut);

Every Console.WriteLine or Console.Write is sent to a file but as I said I am experiencing different behaviours in Windows Service and in standalone Windows environment.

Upvotes: 0

Views: 2829

Answers (3)

2GDev
2GDev

Reputation: 2466

You can't modify System.Environment.NewLine

MSDN Reference

It's a readonly property

public static string NewLine { get; }

And Here you can read that NewLine return always "\r\n".

Next we look into get_NewLine and it is implemented with this IL. You can see it simply returns the "\r\n" string literal.

So I think you can use a Constant inside your application like

public const NEWLINE = "\r\n"; 

And simply use this instead of Environment.NewLine.

Console.WriteLine don't use internally Environment.NewLine instead it use a carriage return followed by a line feed. Reference Here

The default line terminator is a string whose value is a carriage return followed by a line feed ("\r\n" in C#, or vbCrLf in Visual Basic). You can change the line terminator by setting the TextWriter.NewLine property of the Out property to another string. The example provides an illustration.

There is also an example on how to modify this property :

 // Redefine the newline characters to double space.
 Console.Out.NewLine = "\r\n\r\n";

Upvotes: 2

Tomas Jansson
Tomas Jansson

Reputation: 23472

Then I don't think you should use Environment.NewLine. What you see is the exact reason why the have it in the first place. I think you are better off by defining an appSettings that you use and set it to different values for your console application and the windows service application.

Update: Also see Marc Gravell's answer. Even though if it is hard coded I wouldn't try to change it with the motivation as above.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1063774

I'm not convinced by this:

When I move the core framework into a Windows service the Environment.NewLine changes to "\n"

I've checked the IL for get_NewLine(), and it is hard-coded to:

ldstr "\r\n"
ret

So basically; the problem isn't what you think it is; changing Environment.NewLine isn't going to do anything (and: isn't possible).

So: how are you redirecting? I tend to just do something like:

if (!Environment.UserInteractive)
{
    var tw = new SlowWriter(Path.Combine(logPath,"{0}.log"));
    Console.SetError(tw);
    Console.SetOut(tw);
}

where SlowWriter is a custom type (subclasses TextWriter) that makes sure the file doesn't stay open; slower, but pretty robust:

class SlowWriter : TextWriter
{ // this opens and closs each time; slower, but doesn't lock the file
    private readonly string path;
    public SlowWriter(string path)
    {
        this.path = path;
    }
    public override System.Text.Encoding Encoding
    {
        get { return System.Text.Encoding.UTF8; }
    }
    private TextWriter Append()
    {
        var finalPath = string.Format(path, DateTime.UtcNow.ToString("yyyyMMdd"));
        return File.AppendText(finalPath);
    }
    public override void Write(string value)
    {
        lock (this)
        {
            using (var file = Append())
            {
                file.Write(value);
            }
        }
    }
    public override void Write(char[] buffer, int index, int count)
    {
        lock(this)
        {
            using (var file = Append())
            {
                file.Write(buffer, index, count);
            }
        }
    }
    public override void Write(char[] buffer)
    {
        lock (this)
        {
            using (var file = Append())
            {
                file.Write(buffer);
            }
        }
    }
}

Upvotes: 4

Related Questions