From c84d412e8576aa772ef280a26ed3659df4e56e62 Mon Sep 17 00:00:00 2001 From: Jeff Kluge Date: Tue, 10 Mar 2020 12:24:45 -0700 Subject: [PATCH] Add friendly exception message when DismAddPackage returns CBS_E_NOT_APPLICABLE (#93) Add new exception with message and update documentation Fixes #92 --- src/Microsoft.Dism.Tests/DismExceptionTest.cs | 10 ++++ src/Microsoft.Dism/DismApi.AddPackage.cs | 3 ++ src/Microsoft.Dism/DismException.cs | 46 +++++++++++++++++++ src/Microsoft.Dism/NativeConstants.cs | 5 ++ .../Properties/Resources.Designer.cs | 11 ++++- src/Microsoft.Dism/Properties/Resources.resx | 4 ++ 6 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Dism.Tests/DismExceptionTest.cs b/src/Microsoft.Dism.Tests/DismExceptionTest.cs index ee4a950..55b435a 100644 --- a/src/Microsoft.Dism.Tests/DismExceptionTest.cs +++ b/src/Microsoft.Dism.Tests/DismExceptionTest.cs @@ -23,6 +23,16 @@ public void DismOpenSessionsExceptionTest() VerifyDismException(DismApi.DISMAPI_E_OPEN_SESSION_HANDLES, Resources.DismExceptionMessageOpenSessions); } + [Fact] + public void DismPackageNotApplicableExceptionTest() + { + Exception exception = DismException.GetDismExceptionForHResult(unchecked((int)DismApi.CBS_E_NOT_APPLICABLE)); + + exception.ShouldBeOfType(); + + exception.Message.ShouldBe(Resources.DismExceptionMessagePackageNotApplicable); + } + [Fact] public void DismRebootRequiredExceptionTest() { diff --git a/src/Microsoft.Dism/DismApi.AddPackage.cs b/src/Microsoft.Dism/DismApi.AddPackage.cs index 308dd77..295d93b 100644 --- a/src/Microsoft.Dism/DismApi.AddPackage.cs +++ b/src/Microsoft.Dism/DismApi.AddPackage.cs @@ -19,6 +19,7 @@ public static partial class DismApi /// Specifies whether to add a package if it has pending online actions. /// When a failure occurs. /// When the operation requires a reboot to complete. + /// When the package is not applicable to the specified session. public static void AddPackage(DismSession session, string packagePath, bool ignoreCheck, bool preventPending) { AddPackage(session, packagePath, ignoreCheck, preventPending, null); @@ -35,6 +36,7 @@ public static void AddPackage(DismSession session, string packagePath, bool igno /// When a failure occurs. /// When the user requested the operation be canceled. /// When the operation requires a reboot to complete. + /// When the package is not applicable to the specified session. public static void AddPackage(DismSession session, string packagePath, bool ignoreCheck, bool preventPending, Microsoft.Dism.DismProgressCallback progressCallback) { AddPackage(session, packagePath, ignoreCheck, preventPending, progressCallback, null); @@ -52,6 +54,7 @@ public static void AddPackage(DismSession session, string packagePath, bool igno /// When a failure occurs. /// When the user requested the operation be canceled. /// When the operation requires a reboot to complete. + /// When the package is not applicable to the specified session. public static void AddPackage(DismSession session, string packagePath, bool ignoreCheck, bool preventPending, Microsoft.Dism.DismProgressCallback progressCallback, object userData) { // Create a DismProgress object to wrap the callback and allow cancellation diff --git a/src/Microsoft.Dism/DismException.cs b/src/Microsoft.Dism/DismException.cs index 23c83fe..9d2c5d4 100644 --- a/src/Microsoft.Dism/DismException.cs +++ b/src/Microsoft.Dism/DismException.cs @@ -99,6 +99,9 @@ internal static Exception GetDismExceptionForHResult(int errorCode) case DismApi.DISMAPI_E_OPEN_SESSION_HANDLES: // User has not called CloseSession() on open sessions return new DismOpenSessionsException(errorCode); + + case DismApi.CBS_E_NOT_APPLICABLE: + return new DismPackageNotApplicableException(errorCode); } // Attempt to get an error message from the DismApi @@ -212,6 +215,49 @@ private DismOpenSessionsException(SerializationInfo serializationInfo, Streaming } } + /// + /// The exception that is thrown when a package is not applicable to a particular session. + /// + [Serializable] + public sealed class DismPackageNotApplicableException : DismException + { + /// + /// Initializes a new instance of the class. + /// + /// The error code to associate with the exception. + public DismPackageNotApplicableException(int errorCode) + : base(errorCode, Resources.DismExceptionMessagePackageNotApplicable) + { + } + + /// + /// Initializes a new instance of the class. + /// + public DismPackageNotApplicableException() + : base() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public DismPackageNotApplicableException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception, or a null reference ( in Visual Basic) if no inner exception is specified. + public DismPackageNotApplicableException(string message, Exception innerException) + : base(message, innerException) + { + } + } + /// /// The exception that is thrown when the previous operations requires a reboot. /// diff --git a/src/Microsoft.Dism/NativeConstants.cs b/src/Microsoft.Dism/NativeConstants.cs index 88bcf0c..198917f 100644 --- a/src/Microsoft.Dism/NativeConstants.cs +++ b/src/Microsoft.Dism/NativeConstants.cs @@ -182,6 +182,11 @@ public static partial class DismApi /// The requested operation is successful. The DISM session needs to be reloaded. /// internal const int DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED = 0x00000001; // 1 + + /// + /// The specified package is not applicable. + /// + internal const uint CBS_E_NOT_APPLICABLE = 0x800F081E; #pragma warning restore SA1310 // Field names must not contain underscore } } \ No newline at end of file diff --git a/src/Microsoft.Dism/Properties/Resources.Designer.cs b/src/Microsoft.Dism/Properties/Resources.Designer.cs index e7d3eaf..f49c20f 100644 --- a/src/Microsoft.Dism/Properties/Resources.Designer.cs +++ b/src/Microsoft.Dism/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.Dism.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -78,6 +78,15 @@ internal static string DismExceptionMessageOpenSessions { } } + /// + /// Looks up a localized string similar to The specified package is not applicable.. + /// + internal static string DismExceptionMessagePackageNotApplicable { + get { + return ResourceManager.GetString("DismExceptionMessagePackageNotApplicable", resourceCulture); + } + } + /// /// Looks up a localized string similar to A restart is required to complete the operation.. /// diff --git a/src/Microsoft.Dism/Properties/Resources.resx b/src/Microsoft.Dism/Properties/Resources.resx index c363c30..b589f7a 100644 --- a/src/Microsoft.Dism/Properties/Resources.resx +++ b/src/Microsoft.Dism/Properties/Resources.resx @@ -125,6 +125,10 @@ There are one or more open sessions. Exception message when there are one or more open sessions and a user calls the Shutdown() method. + + The specified package is not applicable. + Exception message when a package is not applicable. + A restart is required to complete the operation. Exception message when an operation requires a reboot.