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
- Geometry3D.cs
- SqlUDTStorage.cs
- DispatcherEventArgs.cs
- XmlUtf8RawTextWriter.cs
- CodeMemberProperty.cs
- AssociationProvider.cs
- WindowsUpDown.cs
- XmlWriterSettings.cs
- DataGridViewRowHeaderCell.cs
- HtmlInputText.cs
- BitmapVisualManager.cs
- DateTimeOffsetStorage.cs
- AndCondition.cs
- GifBitmapDecoder.cs
- ExpressionBindingCollection.cs
- OutputCacheModule.cs
- WebPartZoneAutoFormat.cs
- ServiceNotStartedException.cs
- FontFamilyValueSerializer.cs
- UrlPath.cs
- oledbmetadatacolumnnames.cs
- _BasicClient.cs
- thaishape.cs
- datacache.cs
- SystemUdpStatistics.cs
- TableAutomationPeer.cs
- Rotation3DKeyFrameCollection.cs
- DataControlFieldCollection.cs
- RootProfilePropertySettingsCollection.cs
- Cast.cs
- ReadOnlyPropertyMetadata.cs
- AttributeProviderAttribute.cs
- GuidTagList.cs
- StringUtil.cs
- XomlDesignerLoader.cs
- FrameAutomationPeer.cs
- WebPartVerb.cs
- Range.cs
- ZipIOExtraFieldElement.cs
- CompositeDispatchFormatter.cs
- URLAttribute.cs
- DependencyProperty.cs
- _TimerThread.cs
- ObjectStateFormatter.cs
- UriSection.cs
- TreeViewHitTestInfo.cs
- Directory.cs
- RuntimeComponentFilter.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- UrlMappingsModule.cs
- UnSafeCharBuffer.cs
- NamespaceList.cs
- XmlTextAttribute.cs
- ELinqQueryState.cs
- ManipulationDevice.cs
- SkinBuilder.cs
- Stream.cs
- WorkflowInspectionServices.cs
- ControlUtil.cs
- PropertyEmitter.cs
- SettingsProperty.cs
- WindowsListViewItem.cs
- MemoryResponseElement.cs
- DocumentViewerBaseAutomationPeer.cs
- _ConnectStream.cs
- HGlobalSafeHandle.cs
- CheckedListBox.cs
- Exceptions.cs
- MergeFilterQuery.cs
- ContainsSearchOperator.cs
- CompositeKey.cs
- SafeThemeHandle.cs
- KeyValueConfigurationElement.cs
- DrawingImage.cs
- DataGridViewTextBoxCell.cs
- AssemblyBuilderData.cs
- WindowsMenu.cs
- Monitor.cs
- NeutralResourcesLanguageAttribute.cs
- Collection.cs
- WebZone.cs
- RedirectionProxy.cs
- OleCmdHelper.cs
- AnimationException.cs
- SystemWebExtensionsSectionGroup.cs
- ServiceHttpHandlerFactory.cs
- sitestring.cs
- ExtenderControl.cs
- WindowsHyperlink.cs
- DataGridViewTextBoxColumn.cs
- EventSource.cs
- webeventbuffer.cs
- RegistryPermission.cs
- FilterElement.cs
- LogEntrySerializationException.cs
- ToolStripOverflowButton.cs
- WebPartDisplayMode.cs
- WebBrowser.cs
- SamlNameIdentifierClaimResource.cs
- TextContainerChangedEventArgs.cs