1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Globalization; 6 using System.Runtime.InteropServices; 7 using System.Runtime.Serialization; 8 using System.Text; 9 10 namespace System.ComponentModel 11 { 12 /// <summary> 13 /// The exception that is thrown for a Win32 error code. 14 /// </summary> 15 [Serializable] 16 [System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] 17 public partial class Win32Exception : ExternalException, ISerializable 18 { 19 private const int E_FAIL = unchecked((int)0x80004005); 20 21 /// <summary> 22 /// Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the last Win32 error 23 /// that occurred. 24 /// </summary> Win32Exception()25 public Win32Exception() : this(Marshal.GetLastWin32Error()) 26 { 27 } 28 29 /// <summary> 30 /// Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error. 31 /// </summary> Win32Exception(int error)32 public Win32Exception(int error) : this(error, GetErrorMessage(error)) 33 { 34 } 35 /// <summary> 36 /// Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error and the 37 /// specified detailed description. 38 /// </summary> Win32Exception(int error, string message)39 public Win32Exception(int error, string message) : base(message) 40 { 41 NativeErrorCode = error; 42 } 43 44 /// <summary> 45 /// Initializes a new instance of the Exception class with a specified error message. 46 /// </summary> Win32Exception(string message)47 public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message) 48 { 49 } 50 51 /// <summary> 52 /// Initializes a new instance of the Exception class with a specified error message and a 53 /// reference to the inner exception that is the cause of this exception. 54 /// </summary> Win32Exception(string message, Exception innerException)55 public Win32Exception(string message, Exception innerException) : base(message, innerException) 56 { 57 NativeErrorCode = Marshal.GetLastWin32Error(); 58 } 59 Win32Exception(SerializationInfo info, StreamingContext context)60 protected Win32Exception(SerializationInfo info, StreamingContext context) : base(info, context) 61 { 62 NativeErrorCode = info.GetInt32(nameof(NativeErrorCode)); 63 } 64 GetObjectData(SerializationInfo info, StreamingContext context)65 public override void GetObjectData(SerializationInfo info, StreamingContext context) 66 { 67 base.GetObjectData(info, context); 68 info.AddValue(nameof(NativeErrorCode), NativeErrorCode); 69 } 70 71 /// <summary> 72 /// Represents the Win32 error code associated with this exception. This field is read-only. 73 /// </summary> 74 public int NativeErrorCode { get; } 75 76 /// <summary> 77 /// Returns a string that contains the <see cref="NativeErrorCode"/>, or <see cref="Exception.HResult"/>, or both. 78 /// </summary> 79 /// <returns>A string that represents the <see cref="NativeErrorCode"/>, or <see cref="Exception.HResult"/>, or both.</returns> ToString()80 public override string ToString() 81 { 82 if (NativeErrorCode == 0 || NativeErrorCode == HResult) 83 { 84 return base.ToString(); 85 } 86 87 string message = Message; 88 string className = GetType().ToString(); 89 StringBuilder s = new StringBuilder(className); 90 string nativeErrorString = NativeErrorCode < 0 91 ? string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", NativeErrorCode) 92 : NativeErrorCode.ToString(CultureInfo.InvariantCulture); 93 if (HResult == E_FAIL) 94 { 95 s.AppendFormat(CultureInfo.InvariantCulture, " ({0})", nativeErrorString); 96 } 97 else 98 { 99 s.AppendFormat(CultureInfo.InvariantCulture, " ({0:X8}, {1})", HResult, nativeErrorString); 100 } 101 102 if (!(String.IsNullOrEmpty(message))) 103 { 104 s.Append(": "); 105 s.Append(message); 106 } 107 108 Exception innerException = InnerException; 109 if (innerException != null) 110 { 111 s.Append(" ---> "); 112 s.Append(innerException.ToString()); 113 } 114 115 string stackTrace = StackTrace; 116 if (stackTrace != null) 117 { 118 s.AppendLine(); 119 s.Append(stackTrace); 120 } 121 122 return s.ToString(); 123 } 124 } 125 } 126