Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / AvTrace.cs / 1 / AvTrace.cs
/****************************************************************************\ * * File: AvTrace.cs * * This class wraps a System.Diagnostics.TraceSource. The purpose of * wrapping is so that we can have a common point of enabling/disabling * without perf effect. This is also where we standardize the output * we produce, to enable more effective trace filters, trace listeners, * and post-processing tools. * * Copyright (C) by Microsoft Corporation. All rights reserved. * \***************************************************************************/ #define TRACE using System; using System.Diagnostics; using System.Security; using System.Security.Permissions; using System.Text; using System.Reflection; using System.Collections; using System.Windows; using Microsoft.Win32; using MS.Win32; using MS.Internal.WindowsBase; namespace MS.Internal { internal class AvTrace { // // AvTrace constructor // // Parameters: // getTraceSourceDelegate and clearTraceSourceDelegate are for accessing the // TraceSource (that corresponds to this AvTrace) from PresentationTraceSources. // public AvTrace( GetTraceSourceDelegate getTraceSourceDelegate, ClearTraceSourceDelegate clearTraceSourceDelegate ) { _getTraceSourceDelegate = getTraceSourceDelegate; _clearTraceSourceDelegate = clearTraceSourceDelegate; // Get notified when we need to check the registry and debugger attached-ness. PresentationTraceSources.TraceRefresh += new TraceRefreshEventHandler(Refresh); // Fetch and cache the TraceSource from PresentationTraceSources Initialize(); } // // Refresh this trace source -- see if it needs to be enabled // because registry setting has changed or debugger is attached. // // To re-read the config file, call System.Diagnostics.Trace.Refresh() . // public void Refresh() { // Cause the registry to be re-read in case it's changed. _enabledInRegistry = null; // Re-initialize everything Initialize(); } // // Don't call Trace unless this property is true. // Note that this can be false, even though IsEnabledOverride is true (this happens when // running under a debugger). See IsEnabledOverride for a description. // public bool IsEnabled { get { return _isEnabled; } } // // If this flag is set, Trace doesn't automatically add the .GetHashCode and .GetType // to the format string. // public bool SuppressGeneratedParameters { get { return _suppressGeneratedParameters; } set { _suppressGeneratedParameters = value; } } // // IsEnabledOverride is used as a special override. This can be true even if IsEnabled is false. // The scenario is for >=Warning traces; in this case, despite the fact that tracing wasn't enabled // in the registry, we want to send traces anyway if a debugger is attached. Clients of the trace classes // have to decide to call IsEnabledOverride in these cases rather than IsEnabled. // Note that this could be cleaner, but was done to minimize risk as a late checkin; the key goal being // that tracing only run when enabled. // public bool IsEnabledOverride { get { return _traceSource != null; } } // // EnabledByDebugger is a special override that causes AvTrace to be IsEnabled, when we're running // under a debugger, despite the fact that the registry hasn't enabled tracing. This was added // so that TraceData could cause tracing to be enabled when running under the debugger. Other classes // only enable tracing based on the registry key. See also the common on IsEnabledOverride. And like the note there, // this couuld be more straightforward, but is designed this way to mitigate risk. // public bool EnabledByDebugger { get { return _enabledByDebugger; } set { _enabledByDebugger = value; if( _enabledByDebugger ) { if( !IsEnabled && IsDebuggerAttached() ) { _isEnabled = true; } } else { if( IsEnabled && !IsWpfTracingEnabledInRegistry() && !_hasBeenRefreshed ) { _isEnabled = false; } } } } // // This method is called to indicate that PresentationTraceSources.Refresh // has been called. When that method has been called, we'll allow // tracing to be enabled. // static public void OnRefresh() { _hasBeenRefreshed = true; } // // Extra args passed to Trace call will be forwarded to listeners of TraceExtraMessages // public event AvTraceEventHandler TraceExtraMessages; // // Internal initialization // void Initialize( ) { // Decide if we should actually create a TraceSource instance (doing so isn't free, // so we don't want to do it if we can avoid it). if( ShouldCreateTraceSources() ) { // Get TraceSource from the PresentationTraceSources // (this call will indirectly create the TraceSource if one doesn't already exist) _traceSource = _getTraceSourceDelegate(); // We go enabled if tracing is enabled in the registry, if // PresentationTraceSources.Refresh has been called, or if we're in the debugger // and the debugger is supposed to enable tracing. _isEnabled = IsWpfTracingEnabledInRegistry() || _hasBeenRefreshed || _enabledByDebugger ; } else { _clearTraceSourceDelegate(); _traceSource = null; _isEnabled = false; } } // // See if tracing should be enabled. It should if we're in // a debugger, or if the registry key is set, or if // PresentationTraceSources.Refresh has been called. // (We do this so that in the default case, we don't even create // the TraceSource.) // static private bool ShouldCreateTraceSources() { if( IsWpfTracingEnabledInRegistry() || IsDebuggerAttached() || _hasBeenRefreshed ) { return true; } return false; } /// /// Read the registry to see if WPF tracing is allowed /// ////// Critical - Calls critical code (ReadRegistryValue) /// TreatAsSafe - We consider this safe to expose from the internet, because /// the value being read is just a flag which enables/disables tracing, /// and it is only read. The flag is "ManagedTracing", unber HKCU. If it is set to /// 1, tracing (from System.Diagnostics) can be enabled/configured using a .config file. /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] static internal bool IsWpfTracingEnabledInRegistry() { // First time this is called, initialize from the registry if( _enabledInRegistry == null ) { bool enabled = false; object keyValue = SecurityHelper.ReadRegistryValue( Registry.CurrentUser, @"Software\Microsoft\Tracing\WPF", "ManagedTracing"); if( keyValue is int && ((int) keyValue) == 1 ) { enabled = true; } // Update the static. Doing this last protects us from threading problems; worse case, multiple // threads will set the same value into it. _enabledInRegistry = enabled; } return (bool) _enabledInRegistry; } // // Check for an attached debugger. // internal static bool IsDebuggerAttached() { return Debugger.IsAttached || SafeNativeMethods.IsDebuggerPresent(); } // // Trace an event // // note: labels start at index 1, parameters start at index 0 // public void Trace( TraceEventType type, int eventId, string message, string[] labels, object[] parameters ) { // Don't bother building the string if this trace is going to be ignored. if( _traceSource == null || !_traceSource.Switch.ShouldTrace( type )) { return; } // Compose the trace string. AvTraceBuilder traceBuilder = new AvTraceBuilder(message); // Holds the format string ArrayList arrayList = new ArrayList(); // Holds the combined labels & parameters arrays. int formatIndex = 0; if (parameters != null && labels != null && labels.Length > 0) { int i = 1, j = 0; for( ; i < labels.Length && j < parameters.Length; i++, j++ ) { // Append to the format string a "; {0} = '{1}'", where the index increments (e.g. the second iteration will // produce {2} & {3}). traceBuilder.Append("; {" + (formatIndex++).ToString() + "}='{" + (formatIndex++).ToString() + "}'" ); // If this parameter is null, convert to ""; otherwise, when a string.format is ultimately called // it produces bad results. if( parameters[j] == null ) { parameters[j] = " "; } // Otherwise, if this is an interesting object, add the hash code and type to // the format string explicitely. else if( !SuppressGeneratedParameters && parameters[j].GetType() != typeof(string) && !(parameters[j] is ValueType) && !(parameters[j] is Type) && !(parameters[j] is DependencyProperty) ) { traceBuilder.Append("; " + labels[i].ToString() + ".HashCode='" + GetHashCodeHelper(parameters[j]).ToString() + "'" ); traceBuilder.Append("; " + labels[i].ToString() + ".Type='" + GetTypeHelper(parameters[j]).ToString() + "'" ); } // Add the label & parameter to the combined list. // (As an optimization, the generated classes could pre-allocate a thread-safe static array, to avoid // this allocation and the ToArray allocation below.) arrayList.Add( labels[i] ); arrayList.Add( parameters[j] ); } // It's OK if we terminate because we have more lables than parameters; // this is used by traces to have out-values in the Stop message. if( TraceExtraMessages != null && j < parameters.Length) { TraceExtraMessages( traceBuilder, parameters, j ); } } // Send the trace _traceSource.TraceEvent( type, eventId, traceBuilder.ToString(), arrayList.ToArray() ); // When in the debugger, always flush the output, to guarantee that the // traces and other info (e.g. exceptions) get interleaved correctly. if( IsDebuggerAttached() ) { _traceSource.Flush(); } } // // Trace an event, as both a TraceEventType.Start and TraceEventType.Stop. // (information is contained in the Start event) // public void TraceStartStop( int eventID, string message, string[] labels, Object[] parameters ) { Trace( TraceEventType.Start, eventID, message, labels, parameters ); _traceSource.TraceEvent( TraceEventType.Stop, eventID); } // // Convert the value to a string, even if the system conversion throws // an exception. // static public string ToStringHelper(object value) { if (value == null) return " "; // PreSharp uses message numbers that the C# compiler doesn't know about. // Disable the C# complaints, per the PreSharp documentation. #pragma warning disable 1634, 1691 // PreSharp complains about catching NullReference (and other) exceptions. // In this case, these are precisely the ones we want to catch the most, // so that we can still print some kind of diagnostic information even // about objects that implement ToString poorly. #pragma warning disable 56500 string result; try { result = value.ToString(); } catch { result = " "; } #pragma warning restore 56500 #pragma warning restore 1634, 1691 return result; } // // Return the type name for the given value // static public string TypeName(object value) { if (value == null) return " "; return value.GetType().Name; } // // This is a wrapper around Object.GetHashCode. We use this because // individual GetHashCode implementations can be unreliable. // static public int GetHashCodeHelper(object value ) { try { return (value != null) ? value.GetHashCode() : 0; } catch( Exception e ) { if( CriticalExceptions.IsCriticalException(e) && !(e is System.NullReferenceException) ) { throw; } return 0; } } // // Get an object's type, returning typeof(ValueType) for // the null case. // static public Type GetTypeHelper(object value) { if (value == null) { return typeof(ValueType); } return value.GetType(); } // // Private state // // Flag showing if tracing is enabled. See also the IsEnabledOverride property bool _isEnabled = false; // If this is set, then having the debugger attached is an excuse to be enabled, // even if the registry flag isn't set. bool _enabledByDebugger = false; // If this flag is set, Trace doesn't automatically add the .GetHashCode and .GetType // to the format string. bool _suppressGeneratedParameters = false; // If this flag is set, tracing will be enabled, as if it was set in the registry. static bool _hasBeenRefreshed = false; // Delegates to create and remove the TraceSource instance GetTraceSourceDelegate _getTraceSourceDelegate; ClearTraceSourceDelegate _clearTraceSourceDelegate; // Cache of TraceSource instance; real value resides in PresentationTraceSources. TraceSource _traceSource; // Cache used by IsWpfTracingEnabledInRegistry static Nullable _enabledInRegistry = null; } internal delegate void AvTraceEventHandler( AvTraceBuilder traceBuilder, object[] parameters, int start ); internal class AvTraceBuilder { StringBuilder _sb; public AvTraceBuilder() { _sb = new StringBuilder(); } public AvTraceBuilder( string message ) { _sb = new StringBuilder( message ); } public void Append( string message ) { _sb.Append( message ); } public void AppendFormat( string message, params object[] args ) { object[] argstrs = new object[args.Length]; for (int i = 0; i < args.Length; ++i) { string s = args[i] as string; argstrs[i] = (s != null) ? s : AvTrace.ToStringHelper(args[i]); } _sb.AppendFormat( message, argstrs ); } public void AppendFormat( string message, object arg1 ) { _sb.AppendFormat( message, new object[] { AvTrace.ToStringHelper(arg1) } ); } public void AppendFormat( string message, object arg1, object arg2 ) { _sb.AppendFormat( message, new object[] { AvTrace.ToStringHelper(arg1), AvTrace.ToStringHelper(arg2) } ); } public void AppendFormat( string message, string arg1 ) { _sb.AppendFormat( message, new object[] { arg1 } ); } public void AppendFormat( string message, string arg1, string arg2 ) { _sb.AppendFormat( message, new object[] { arg1, arg2 } ); } public override string ToString( ) { return _sb.ToString(); } } internal delegate TraceSource GetTraceSourceDelegate(); internal delegate void ClearTraceSourceDelegate(); } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /****************************************************************************\ * * File: AvTrace.cs * * This class wraps a System.Diagnostics.TraceSource. The purpose of * wrapping is so that we can have a common point of enabling/disabling * without perf effect. This is also where we standardize the output * we produce, to enable more effective trace filters, trace listeners, * and post-processing tools. * * Copyright (C) by Microsoft Corporation. All rights reserved. * \***************************************************************************/ #define TRACE using System; using System.Diagnostics; using System.Security; using System.Security.Permissions; using System.Text; using System.Reflection; using System.Collections; using System.Windows; using Microsoft.Win32; using MS.Win32; using MS.Internal.WindowsBase; namespace MS.Internal { internal class AvTrace { // // AvTrace constructor // // Parameters: // getTraceSourceDelegate and clearTraceSourceDelegate are for accessing the // TraceSource (that corresponds to this AvTrace) from PresentationTraceSources. // public AvTrace( GetTraceSourceDelegate getTraceSourceDelegate, ClearTraceSourceDelegate clearTraceSourceDelegate ) { _getTraceSourceDelegate = getTraceSourceDelegate; _clearTraceSourceDelegate = clearTraceSourceDelegate; // Get notified when we need to check the registry and debugger attached-ness. PresentationTraceSources.TraceRefresh += new TraceRefreshEventHandler(Refresh); // Fetch and cache the TraceSource from PresentationTraceSources Initialize(); } // // Refresh this trace source -- see if it needs to be enabled // because registry setting has changed or debugger is attached. // // To re-read the config file, call System.Diagnostics.Trace.Refresh() . // public void Refresh() { // Cause the registry to be re-read in case it's changed. _enabledInRegistry = null; // Re-initialize everything Initialize(); } // // Don't call Trace unless this property is true. // Note that this can be false, even though IsEnabledOverride is true (this happens when // running under a debugger). See IsEnabledOverride for a description. // public bool IsEnabled { get { return _isEnabled; } } // // If this flag is set, Trace doesn't automatically add the .GetHashCode and .GetType // to the format string. // public bool SuppressGeneratedParameters { get { return _suppressGeneratedParameters; } set { _suppressGeneratedParameters = value; } } // // IsEnabledOverride is used as a special override. This can be true even if IsEnabled is false. // The scenario is for >=Warning traces; in this case, despite the fact that tracing wasn't enabled // in the registry, we want to send traces anyway if a debugger is attached. Clients of the trace classes // have to decide to call IsEnabledOverride in these cases rather than IsEnabled. // Note that this could be cleaner, but was done to minimize risk as a late checkin; the key goal being // that tracing only run when enabled. // public bool IsEnabledOverride { get { return _traceSource != null; } } // // EnabledByDebugger is a special override that causes AvTrace to be IsEnabled, when we're running // under a debugger, despite the fact that the registry hasn't enabled tracing. This was added // so that TraceData could cause tracing to be enabled when running under the debugger. Other classes // only enable tracing based on the registry key. See also the common on IsEnabledOverride. And like the note there, // this couuld be more straightforward, but is designed this way to mitigate risk. // public bool EnabledByDebugger { get { return _enabledByDebugger; } set { _enabledByDebugger = value; if( _enabledByDebugger ) { if( !IsEnabled && IsDebuggerAttached() ) { _isEnabled = true; } } else { if( IsEnabled && !IsWpfTracingEnabledInRegistry() && !_hasBeenRefreshed ) { _isEnabled = false; } } } } // // This method is called to indicate that PresentationTraceSources.Refresh // has been called. When that method has been called, we'll allow // tracing to be enabled. // static public void OnRefresh() { _hasBeenRefreshed = true; } // // Extra args passed to Trace call will be forwarded to listeners of TraceExtraMessages // public event AvTraceEventHandler TraceExtraMessages; // // Internal initialization // void Initialize( ) { // Decide if we should actually create a TraceSource instance (doing so isn't free, // so we don't want to do it if we can avoid it). if( ShouldCreateTraceSources() ) { // Get TraceSource from the PresentationTraceSources // (this call will indirectly create the TraceSource if one doesn't already exist) _traceSource = _getTraceSourceDelegate(); // We go enabled if tracing is enabled in the registry, if // PresentationTraceSources.Refresh has been called, or if we're in the debugger // and the debugger is supposed to enable tracing. _isEnabled = IsWpfTracingEnabledInRegistry() || _hasBeenRefreshed || _enabledByDebugger ; } else { _clearTraceSourceDelegate(); _traceSource = null; _isEnabled = false; } } // // See if tracing should be enabled. It should if we're in // a debugger, or if the registry key is set, or if // PresentationTraceSources.Refresh has been called. // (We do this so that in the default case, we don't even create // the TraceSource.) // static private bool ShouldCreateTraceSources() { if( IsWpfTracingEnabledInRegistry() || IsDebuggerAttached() || _hasBeenRefreshed ) { return true; } return false; } /// /// Read the registry to see if WPF tracing is allowed /// /// /// Critical - Calls critical code (ReadRegistryValue) /// TreatAsSafe - We consider this safe to expose from the internet, because /// the value being read is just a flag which enables/disables tracing, /// and it is only read. The flag is "ManagedTracing", unber HKCU. If it is set to /// 1, tracing (from System.Diagnostics) can be enabled/configured using a .config file. /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] static internal bool IsWpfTracingEnabledInRegistry() { // First time this is called, initialize from the registry if( _enabledInRegistry == null ) { bool enabled = false; object keyValue = SecurityHelper.ReadRegistryValue( Registry.CurrentUser, @"Software\Microsoft\Tracing\WPF", "ManagedTracing"); if( keyValue is int && ((int) keyValue) == 1 ) { enabled = true; } // Update the static. Doing this last protects us from threading problems; worse case, multiple // threads will set the same value into it. _enabledInRegistry = enabled; } return (bool) _enabledInRegistry; } // // Check for an attached debugger. // internal static bool IsDebuggerAttached() { return Debugger.IsAttached || SafeNativeMethods.IsDebuggerPresent(); } // // Trace an event // // note: labels start at index 1, parameters start at index 0 // public void Trace( TraceEventType type, int eventId, string message, string[] labels, object[] parameters ) { // Don't bother building the string if this trace is going to be ignored. if( _traceSource == null || !_traceSource.Switch.ShouldTrace( type )) { return; } // Compose the trace string. AvTraceBuilder traceBuilder = new AvTraceBuilder(message); // Holds the format string ArrayList arrayList = new ArrayList(); // Holds the combined labels & parameters arrays. int formatIndex = 0; if (parameters != null && labels != null && labels.Length > 0) { int i = 1, j = 0; for( ; i < labels.Length && j < parameters.Length; i++, j++ ) { // Append to the format string a "; {0} = '{1}'", where the index increments (e.g. the second iteration will // produce {2} & {3}). traceBuilder.Append("; {" + (formatIndex++).ToString() + "}='{" + (formatIndex++).ToString() + "}'" ); // If this parameter is null, convert to ""; otherwise, when a string.format is ultimately called // it produces bad results. if( parameters[j] == null ) { parameters[j] = " "; } // Otherwise, if this is an interesting object, add the hash code and type to // the format string explicitely. else if( !SuppressGeneratedParameters && parameters[j].GetType() != typeof(string) && !(parameters[j] is ValueType) && !(parameters[j] is Type) && !(parameters[j] is DependencyProperty) ) { traceBuilder.Append("; " + labels[i].ToString() + ".HashCode='" + GetHashCodeHelper(parameters[j]).ToString() + "'" ); traceBuilder.Append("; " + labels[i].ToString() + ".Type='" + GetTypeHelper(parameters[j]).ToString() + "'" ); } // Add the label & parameter to the combined list. // (As an optimization, the generated classes could pre-allocate a thread-safe static array, to avoid // this allocation and the ToArray allocation below.) arrayList.Add( labels[i] ); arrayList.Add( parameters[j] ); } // It's OK if we terminate because we have more lables than parameters; // this is used by traces to have out-values in the Stop message. if( TraceExtraMessages != null && j < parameters.Length) { TraceExtraMessages( traceBuilder, parameters, j ); } } // Send the trace _traceSource.TraceEvent( type, eventId, traceBuilder.ToString(), arrayList.ToArray() ); // When in the debugger, always flush the output, to guarantee that the // traces and other info (e.g. exceptions) get interleaved correctly. if( IsDebuggerAttached() ) { _traceSource.Flush(); } } // // Trace an event, as both a TraceEventType.Start and TraceEventType.Stop. // (information is contained in the Start event) // public void TraceStartStop( int eventID, string message, string[] labels, Object[] parameters ) { Trace( TraceEventType.Start, eventID, message, labels, parameters ); _traceSource.TraceEvent( TraceEventType.Stop, eventID); } // // Convert the value to a string, even if the system conversion throws // an exception. // static public string ToStringHelper(object value) { if (value == null) return " "; // PreSharp uses message numbers that the C# compiler doesn't know about. // Disable the C# complaints, per the PreSharp documentation. #pragma warning disable 1634, 1691 // PreSharp complains about catching NullReference (and other) exceptions. // In this case, these are precisely the ones we want to catch the most, // so that we can still print some kind of diagnostic information even // about objects that implement ToString poorly. #pragma warning disable 56500 string result; try { result = value.ToString(); } catch { result = " "; } #pragma warning restore 56500 #pragma warning restore 1634, 1691 return result; } // // Return the type name for the given value // static public string TypeName(object value) { if (value == null) return " "; return value.GetType().Name; } // // This is a wrapper around Object.GetHashCode. We use this because // individual GetHashCode implementations can be unreliable. // static public int GetHashCodeHelper(object value ) { try { return (value != null) ? value.GetHashCode() : 0; } catch( Exception e ) { if( CriticalExceptions.IsCriticalException(e) && !(e is System.NullReferenceException) ) { throw; } return 0; } } // // Get an object's type, returning typeof(ValueType) for // the null case. // static public Type GetTypeHelper(object value) { if (value == null) { return typeof(ValueType); } return value.GetType(); } // // Private state // // Flag showing if tracing is enabled. See also the IsEnabledOverride property bool _isEnabled = false; // If this is set, then having the debugger attached is an excuse to be enabled, // even if the registry flag isn't set. bool _enabledByDebugger = false; // If this flag is set, Trace doesn't automatically add the .GetHashCode and .GetType // to the format string. bool _suppressGeneratedParameters = false; // If this flag is set, tracing will be enabled, as if it was set in the registry. static bool _hasBeenRefreshed = false; // Delegates to create and remove the TraceSource instance GetTraceSourceDelegate _getTraceSourceDelegate; ClearTraceSourceDelegate _clearTraceSourceDelegate; // Cache of TraceSource instance; real value resides in PresentationTraceSources. TraceSource _traceSource; // Cache used by IsWpfTracingEnabledInRegistry static Nullable _enabledInRegistry = null; } internal delegate void AvTraceEventHandler( AvTraceBuilder traceBuilder, object[] parameters, int start ); internal class AvTraceBuilder { StringBuilder _sb; public AvTraceBuilder() { _sb = new StringBuilder(); } public AvTraceBuilder( string message ) { _sb = new StringBuilder( message ); } public void Append( string message ) { _sb.Append( message ); } public void AppendFormat( string message, params object[] args ) { object[] argstrs = new object[args.Length]; for (int i = 0; i < args.Length; ++i) { string s = args[i] as string; argstrs[i] = (s != null) ? s : AvTrace.ToStringHelper(args[i]); } _sb.AppendFormat( message, argstrs ); } public void AppendFormat( string message, object arg1 ) { _sb.AppendFormat( message, new object[] { AvTrace.ToStringHelper(arg1) } ); } public void AppendFormat( string message, object arg1, object arg2 ) { _sb.AppendFormat( message, new object[] { AvTrace.ToStringHelper(arg1), AvTrace.ToStringHelper(arg2) } ); } public void AppendFormat( string message, string arg1 ) { _sb.AppendFormat( message, new object[] { arg1 } ); } public void AppendFormat( string message, string arg1, string arg2 ) { _sb.AppendFormat( message, new object[] { arg1, arg2 } ); } public override string ToString( ) { return _sb.ToString(); } } internal delegate TraceSource GetTraceSourceDelegate(); internal delegate void ClearTraceSourceDelegate(); } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Paragraph.cs
- EncryptedPackageFilter.cs
- Timer.cs
- MultiPartWriter.cs
- HandleCollector.cs
- ControlDesigner.cs
- SecurityMode.cs
- QueryOpcode.cs
- XPathExpr.cs
- PriorityChain.cs
- DuplicateWaitObjectException.cs
- StoreAnnotationsMap.cs
- ApplicationInfo.cs
- Serializer.cs
- SettingsSavedEventArgs.cs
- BrushValueSerializer.cs
- AppLevelCompilationSectionCache.cs
- SqlInternalConnectionTds.cs
- MgmtConfigurationRecord.cs
- iisPickupDirectory.cs
- Switch.cs
- PaintValueEventArgs.cs
- XmlCharacterData.cs
- ForEachDesigner.xaml.cs
- DetailsViewUpdateEventArgs.cs
- ThreadAbortException.cs
- ToolboxItemAttribute.cs
- PointCollectionValueSerializer.cs
- RadioButtonPopupAdapter.cs
- DataControlReferenceCollection.cs
- CheckBoxList.cs
- FileRecordSequenceHelper.cs
- Wrapper.cs
- HostExecutionContextManager.cs
- AccessDataSource.cs
- DependencyPropertyHelper.cs
- BuildManagerHost.cs
- NamespaceEmitter.cs
- RepeaterCommandEventArgs.cs
- LinkLabelLinkClickedEvent.cs
- DataPagerCommandEventArgs.cs
- TypeDelegator.cs
- ToggleButtonAutomationPeer.cs
- PackagePartCollection.cs
- GroupItem.cs
- KeyValuePair.cs
- DataGridParentRows.cs
- Shape.cs
- XmlResolver.cs
- SByte.cs
- HttpConfigurationContext.cs
- SqlError.cs
- _ShellExpression.cs
- XamlTreeBuilderBamlRecordWriter.cs
- DataGridViewElement.cs
- EventItfInfo.cs
- mda.cs
- ByteStreamMessageUtility.cs
- SqlAliasesReferenced.cs
- Tuple.cs
- ObjectDataSource.cs
- DataStreamFromComStream.cs
- StylusEventArgs.cs
- OrthographicCamera.cs
- XsltException.cs
- Msmq3PoisonHandler.cs
- StoreItemCollection.cs
- XmlBinaryWriter.cs
- ProjectionCamera.cs
- PriorityQueue.cs
- TraceRecord.cs
- SimpleFileLog.cs
- LinqDataSourceUpdateEventArgs.cs
- SqlBinder.cs
- Utils.cs
- XslVisitor.cs
- ObjectResult.cs
- DecoratedNameAttribute.cs
- Math.cs
- SqlBulkCopyColumnMappingCollection.cs
- ToolStripItemEventArgs.cs
- SqlDataSourceStatusEventArgs.cs
- EdmComplexPropertyAttribute.cs
- ComponentManagerBroker.cs
- DateTimeStorage.cs
- AsyncDataRequest.cs
- MobileControlsSection.cs
- OleDbPropertySetGuid.cs
- ContextStack.cs
- ViewGenResults.cs
- ConfigsHelper.cs
- MethodInfo.cs
- RegexWorker.cs
- UpDownBase.cs
- XmlException.cs
- SecurityCriticalDataForSet.cs
- ErrorActivity.cs
- ApplicationInfo.cs
- X509ScopedServiceCertificateElement.cs
- PolyBezierSegmentFigureLogic.cs