Reputation: 1346
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
Reputation: 2466
You can't modify System.Environment.NewLine
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
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
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