Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CompMod / System / Diagnostics / TextWriterTraceListener.cs / 1305376 / TextWriterTraceListener.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Diagnostics {
using System;
using System.IO;
using System.Text;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.IO.Ports;
using Microsoft.Win32;
using System.Runtime.Versioning;
///
/// Directs tracing or debugging output to
/// a or to a ,
/// such as or .
///
[HostProtection(Synchronization=true)]
public class TextWriterTraceListener : TraceListener {
internal TextWriter writer;
String fileName = null;
///
/// Initializes a new instance of the class with
///
/// as the output recipient.
///
public TextWriterTraceListener() {
}
///
/// Initializes a new instance of the class, using the
/// stream as the recipient of the debugging and tracing output.
///
public TextWriterTraceListener(Stream stream)
: this(stream, string.Empty) {
}
///
/// Initializes a new instance of the class with the
/// specified name and using the stream as the recipient of the debugging and tracing output.
///
public TextWriterTraceListener(Stream stream, string name)
: base(name) {
if (stream == null) throw new ArgumentNullException("stream");
this.writer = new StreamWriter(stream);
}
///
/// Initializes a new instance of the class using the
/// specified writer as recipient of the tracing or debugging output.
///
public TextWriterTraceListener(TextWriter writer)
: this(writer, string.Empty) {
}
///
/// Initializes a new instance of the class with the
/// specified name and using the specified writer as recipient of the tracing or
/// debugging
/// output.
///
public TextWriterTraceListener(TextWriter writer, string name)
: base(name) {
if (writer == null) throw new ArgumentNullException("writer");
this.writer = writer;
}
///
/// [To be supplied.]
///
[ResourceExposure(ResourceScope.Machine)]
public TextWriterTraceListener(string fileName) {
this.fileName = fileName;
}
///
/// [To be supplied.]
///
[ResourceExposure(ResourceScope.Machine)]
public TextWriterTraceListener(string fileName, string name) : base(name) {
this.fileName = fileName;
}
///
/// Indicates the text writer that receives the tracing
/// or debugging output.
///
public TextWriter Writer {
get {
EnsureWriter();
return writer;
}
set {
writer = value;
}
}
///
/// Closes the so that it no longer
/// receives tracing or debugging output.
///
public override void Close() {
if (writer != null) {
try {
writer.Close();
} catch (ObjectDisposedException) { }
}
writer = null;
}
///
///
///
protected override void Dispose(bool disposing) {
try {
if (disposing) {
this.Close();
}
else {
// clean up resources
if (writer != null)
try {
writer.Close();
} catch (ObjectDisposedException) { }
writer = null;
}
}
finally {
base.Dispose(disposing);
}
}
///
/// Flushes the output buffer for the .
///
public override void Flush() {
if (!EnsureWriter()) return;
try {
writer.Flush();
} catch (ObjectDisposedException) { }
}
///
/// Writes a message
/// to this instance's .
///
public override void Write(string message) {
if (!EnsureWriter()) return;
if (NeedIndent) WriteIndent();
try {
writer.Write(message);
} catch (ObjectDisposedException) { }
}
///
/// Writes a message
/// to this instance's followed by a line terminator. The
/// default line terminator is a carriage return followed by a line feed (\r\n).
///
public override void WriteLine(string message) {
if (!EnsureWriter()) return;
if (NeedIndent) WriteIndent();
try {
writer.WriteLine(message);
NeedIndent = true;
} catch (ObjectDisposedException) { }
}
private static Encoding GetEncodingWithFallback(Encoding encoding)
{
// Clone it and set the "?" replacement fallback
Encoding fallbackEncoding = (Encoding)encoding.Clone();
fallbackEncoding.EncoderFallback = EncoderFallback.ReplacementFallback;
fallbackEncoding.DecoderFallback = DecoderFallback.ReplacementFallback;
return fallbackEncoding;
}
// This uses a machine resource, scoped by the fileName variable.
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal bool EnsureWriter() {
bool ret = true;
if (writer == null) {
ret = false;
if (fileName == null)
return ret;
// StreamWriter by default uses UTF8Encoding which will throw on invalid encoding errors.
// This can cause the internal StreamWriter's state to be irrecoverable. It is bad for tracing
// APIs to throw on encoding errors. Instead, we should provide a "?" replacement fallback
// encoding to substitute illegal chars. For ex, In case of high surrogate character
// D800-DBFF without a following low surrogate character DC00-DFFF
// NOTE: We also need to use an encoding that does't emit BOM whic is StreamWriter's default
Encoding noBOMwithFallback = GetEncodingWithFallback(new UTF8Encoding(false));
// To support multiple appdomains/instances tracing to the same file,
// we will try to open the given file for append but if we encounter
// IO errors, we will prefix the file name with a unique GUID value
// and try one more time
string fullPath = Path.GetFullPath(fileName);
string dirPath = Path.GetDirectoryName(fullPath);
string fileNameOnly = Path.GetFileName(fullPath);
for (int i=0; i<2; i++) {
try {
writer = new StreamWriter(fullPath, true, noBOMwithFallback, 4096);
ret = true;
break;
}
catch (IOException ) {
// Should we do this only for ERROR_SHARING_VIOLATION?
//if (InternalResources.MakeErrorCodeFromHR(Marshal.GetHRForException(ioexc)) == InternalResources.ERROR_SHARING_VIOLATION) {
fileNameOnly = Guid.NewGuid().ToString() + fileNameOnly;
fullPath = Path.Combine(dirPath, fileNameOnly);
continue;
}
catch (UnauthorizedAccessException ) {
//ERROR_ACCESS_DENIED, mostly ACL issues
break;
}
catch (Exception ) {
break;
}
}
if (!ret) {
// Disable tracing to this listener. Every Write will be nop.
// We need to think of a central way to deal with the listener
// init errors in the future. The default should be that we eat
// up any errors from listener and optionally notify the user
fileName = null;
}
}
return ret;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Diagnostics {
using System;
using System.IO;
using System.Text;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.IO.Ports;
using Microsoft.Win32;
using System.Runtime.Versioning;
///
/// Directs tracing or debugging output to
/// a or to a ,
/// such as or .
///
[HostProtection(Synchronization=true)]
public class TextWriterTraceListener : TraceListener {
internal TextWriter writer;
String fileName = null;
///
/// Initializes a new instance of the class with
///
/// as the output recipient.
///
public TextWriterTraceListener() {
}
///
/// Initializes a new instance of the class, using the
/// stream as the recipient of the debugging and tracing output.
///
public TextWriterTraceListener(Stream stream)
: this(stream, string.Empty) {
}
///
/// Initializes a new instance of the class with the
/// specified name and using the stream as the recipient of the debugging and tracing output.
///
public TextWriterTraceListener(Stream stream, string name)
: base(name) {
if (stream == null) throw new ArgumentNullException("stream");
this.writer = new StreamWriter(stream);
}
///
/// Initializes a new instance of the class using the
/// specified writer as recipient of the tracing or debugging output.
///
public TextWriterTraceListener(TextWriter writer)
: this(writer, string.Empty) {
}
///
/// Initializes a new instance of the class with the
/// specified name and using the specified writer as recipient of the tracing or
/// debugging
/// output.
///
public TextWriterTraceListener(TextWriter writer, string name)
: base(name) {
if (writer == null) throw new ArgumentNullException("writer");
this.writer = writer;
}
///
/// [To be supplied.]
///
[ResourceExposure(ResourceScope.Machine)]
public TextWriterTraceListener(string fileName) {
this.fileName = fileName;
}
///
/// [To be supplied.]
///
[ResourceExposure(ResourceScope.Machine)]
public TextWriterTraceListener(string fileName, string name) : base(name) {
this.fileName = fileName;
}
///
/// Indicates the text writer that receives the tracing
/// or debugging output.
///
public TextWriter Writer {
get {
EnsureWriter();
return writer;
}
set {
writer = value;
}
}
///
/// Closes the so that it no longer
/// receives tracing or debugging output.
///
public override void Close() {
if (writer != null) {
try {
writer.Close();
} catch (ObjectDisposedException) { }
}
writer = null;
}
///
///
///
protected override void Dispose(bool disposing) {
try {
if (disposing) {
this.Close();
}
else {
// clean up resources
if (writer != null)
try {
writer.Close();
} catch (ObjectDisposedException) { }
writer = null;
}
}
finally {
base.Dispose(disposing);
}
}
///
/// Flushes the output buffer for the .
///
public override void Flush() {
if (!EnsureWriter()) return;
try {
writer.Flush();
} catch (ObjectDisposedException) { }
}
///
/// Writes a message
/// to this instance's .
///
public override void Write(string message) {
if (!EnsureWriter()) return;
if (NeedIndent) WriteIndent();
try {
writer.Write(message);
} catch (ObjectDisposedException) { }
}
///
/// Writes a message
/// to this instance's followed by a line terminator. The
/// default line terminator is a carriage return followed by a line feed (\r\n).
///
public override void WriteLine(string message) {
if (!EnsureWriter()) return;
if (NeedIndent) WriteIndent();
try {
writer.WriteLine(message);
NeedIndent = true;
} catch (ObjectDisposedException) { }
}
private static Encoding GetEncodingWithFallback(Encoding encoding)
{
// Clone it and set the "?" replacement fallback
Encoding fallbackEncoding = (Encoding)encoding.Clone();
fallbackEncoding.EncoderFallback = EncoderFallback.ReplacementFallback;
fallbackEncoding.DecoderFallback = DecoderFallback.ReplacementFallback;
return fallbackEncoding;
}
// This uses a machine resource, scoped by the fileName variable.
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal bool EnsureWriter() {
bool ret = true;
if (writer == null) {
ret = false;
if (fileName == null)
return ret;
// StreamWriter by default uses UTF8Encoding which will throw on invalid encoding errors.
// This can cause the internal StreamWriter's state to be irrecoverable. It is bad for tracing
// APIs to throw on encoding errors. Instead, we should provide a "?" replacement fallback
// encoding to substitute illegal chars. For ex, In case of high surrogate character
// D800-DBFF without a following low surrogate character DC00-DFFF
// NOTE: We also need to use an encoding that does't emit BOM whic is StreamWriter's default
Encoding noBOMwithFallback = GetEncodingWithFallback(new UTF8Encoding(false));
// To support multiple appdomains/instances tracing to the same file,
// we will try to open the given file for append but if we encounter
// IO errors, we will prefix the file name with a unique GUID value
// and try one more time
string fullPath = Path.GetFullPath(fileName);
string dirPath = Path.GetDirectoryName(fullPath);
string fileNameOnly = Path.GetFileName(fullPath);
for (int i=0; i<2; i++) {
try {
writer = new StreamWriter(fullPath, true, noBOMwithFallback, 4096);
ret = true;
break;
}
catch (IOException ) {
// Should we do this only for ERROR_SHARING_VIOLATION?
//if (InternalResources.MakeErrorCodeFromHR(Marshal.GetHRForException(ioexc)) == InternalResources.ERROR_SHARING_VIOLATION) {
fileNameOnly = Guid.NewGuid().ToString() + fileNameOnly;
fullPath = Path.Combine(dirPath, fileNameOnly);
continue;
}
catch (UnauthorizedAccessException ) {
//ERROR_ACCESS_DENIED, mostly ACL issues
break;
}
catch (Exception ) {
break;
}
}
if (!ret) {
// Disable tracing to this listener. Every Write will be nop.
// We need to think of a central way to deal with the listener
// init errors in the future. The default should be that we eat
// up any errors from listener and optionally notify the user
fileName = null;
}
}
return ret;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RTTypeWrapper.cs
- pingexception.cs
- PrimaryKeyTypeConverter.cs
- HostingPreferredMapPath.cs
- SQLBytes.cs
- PenThreadWorker.cs
- DetailsViewDeletedEventArgs.cs
- PathSegment.cs
- ImageSourceValueSerializer.cs
- SynchronousChannelMergeEnumerator.cs
- _TLSstream.cs
- OnOperation.cs
- TraceContext.cs
- connectionpool.cs
- StylusEditingBehavior.cs
- Clock.cs
- BinaryParser.cs
- GorillaCodec.cs
- MemberDomainMap.cs
- OpenTypeLayout.cs
- OutputCacheSettingsSection.cs
- TimeZone.cs
- WinEventHandler.cs
- RowCache.cs
- TableParaClient.cs
- HtmlUtf8RawTextWriter.cs
- StreamMarshaler.cs
- ObjectItemCollection.cs
- DataGridViewColumnTypeEditor.cs
- ExceptionUtil.cs
- AspNetSynchronizationContext.cs
- DataGridViewCellMouseEventArgs.cs
- xamlnodes.cs
- StreamHelper.cs
- OleDbReferenceCollection.cs
- Int64Animation.cs
- ColorMatrix.cs
- BindingExpression.cs
- uribuilder.cs
- SelfIssuedAuthRSAPKCS1SignatureDeformatter.cs
- RequestSecurityToken.cs
- PathFigureCollectionConverter.cs
- CodeTypeDeclaration.cs
- OperationCanceledException.cs
- ListSortDescription.cs
- XMLSyntaxException.cs
- NetCodeGroup.cs
- ScopelessEnumAttribute.cs
- DecimalFormatter.cs
- HtmlInputSubmit.cs
- Evaluator.cs
- Message.cs
- OleDbParameter.cs
- XmlAnyElementAttribute.cs
- PointAnimationUsingPath.cs
- PrivilegedConfigurationManager.cs
- HyperlinkAutomationPeer.cs
- SponsorHelper.cs
- SqlCommand.cs
- Quad.cs
- OdbcEnvironment.cs
- Base64Stream.cs
- RankException.cs
- sqlcontext.cs
- BulletedListEventArgs.cs
- ElementNotEnabledException.cs
- ConfigurationConverterBase.cs
- AlgoModule.cs
- XamlTemplateSerializer.cs
- DatePickerTextBox.cs
- System.Data_BID.cs
- AvTrace.cs
- Walker.cs
- UnsafeNativeMethods.cs
- WebPartRestoreVerb.cs
- MouseGesture.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- RelationshipConstraintValidator.cs
- DeviceFiltersSection.cs
- SoapProtocolImporter.cs
- DataGridItemEventArgs.cs
- BezierSegment.cs
- BindingListCollectionView.cs
- TreeViewImageIndexConverter.cs
- SchemaImporter.cs
- WebPartCatalogCloseVerb.cs
- CryptoProvider.cs
- UIElementPropertyUndoUnit.cs
- WSUtilitySpecificationVersion.cs
- Binding.cs
- DescriptionAttribute.cs
- RelAssertionDirectKeyIdentifierClause.cs
- DataTableMapping.cs
- PointValueSerializer.cs
- WindowManager.cs
- ErrorHandler.cs
- RawStylusInputCustomDataList.cs
- MouseEventArgs.cs
- FilterableAttribute.cs
- SoapObjectInfo.cs