Skip to content

Commit

Permalink
Add friendly exception message when DismAddPackage returns CBS_E_NOT_…
Browse files Browse the repository at this point in the history
…APPLICABLE (#93)

Add new exception with message and update documentation

Fixes #92
  • Loading branch information
jeffkl authored Mar 10, 2020
1 parent 42e3665 commit c84d412
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/Microsoft.Dism.Tests/DismExceptionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ public void DismOpenSessionsExceptionTest()
VerifyDismException<DismOpenSessionsException>(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<DismPackageNotApplicableException>();

exception.Message.ShouldBe(Resources.DismExceptionMessagePackageNotApplicable);
}

[Fact]
public void DismRebootRequiredExceptionTest()
{
Expand Down
3 changes: 3 additions & 0 deletions src/Microsoft.Dism/DismApi.AddPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public static partial class DismApi
/// <param name="preventPending">Specifies whether to add a package if it has pending online actions.</param>
/// <exception cref="DismException">When a failure occurs.</exception>
/// <exception cref="DismRebootRequiredException">When the operation requires a reboot to complete.</exception>
/// <exception cref="DismPackageNotApplicableException">When the package is not applicable to the specified session.</exception>
public static void AddPackage(DismSession session, string packagePath, bool ignoreCheck, bool preventPending)
{
AddPackage(session, packagePath, ignoreCheck, preventPending, null);
Expand All @@ -35,6 +36,7 @@ public static void AddPackage(DismSession session, string packagePath, bool igno
/// <exception cref="DismException">When a failure occurs.</exception>
/// <exception cref="OperationCanceledException">When the user requested the operation be canceled.</exception>
/// <exception cref="DismRebootRequiredException">When the operation requires a reboot to complete.</exception>
/// <exception cref="DismPackageNotApplicableException">When the package is not applicable to the specified session.</exception>
public static void AddPackage(DismSession session, string packagePath, bool ignoreCheck, bool preventPending, Microsoft.Dism.DismProgressCallback progressCallback)
{
AddPackage(session, packagePath, ignoreCheck, preventPending, progressCallback, null);
Expand All @@ -52,6 +54,7 @@ public static void AddPackage(DismSession session, string packagePath, bool igno
/// <exception cref="DismException">When a failure occurs.</exception>
/// <exception cref="OperationCanceledException">When the user requested the operation be canceled.</exception>
/// <exception cref="DismRebootRequiredException">When the operation requires a reboot to complete.</exception>
/// <exception cref="DismPackageNotApplicableException">When the package is not applicable to the specified session.</exception>
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
Expand Down
46 changes: 46 additions & 0 deletions src/Microsoft.Dism/DismException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -212,6 +215,49 @@ private DismOpenSessionsException(SerializationInfo serializationInfo, Streaming
}
}

/// <summary>
/// The exception that is thrown when a package is not applicable to a particular session.
/// </summary>
[Serializable]
public sealed class DismPackageNotApplicableException : DismException
{
/// <summary>
/// Initializes a new instance of the <see cref="DismPackageNotApplicableException"/> class.
/// </summary>
/// <param name="errorCode">The error code to associate with the exception.</param>
public DismPackageNotApplicableException(int errorCode)
: base(errorCode, Resources.DismExceptionMessagePackageNotApplicable)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="DismPackageNotApplicableException"/> class.
/// </summary>
public DismPackageNotApplicableException()
: base()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="DismPackageNotApplicableException"/> class.
/// </summary>
/// <param name="message">The message that describes the error. </param>
public DismPackageNotApplicableException(string message)
: base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="DismPackageNotApplicableException"/> class.
/// </summary>
/// <param name="message">The message that describes the error. </param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (<see langword="Nothing" /> in Visual Basic) if no inner exception is specified. </param>
public DismPackageNotApplicableException(string message, Exception innerException)
: base(message, innerException)
{
}
}

/// <summary>
/// The exception that is thrown when the previous operations requires a reboot.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Microsoft.Dism/NativeConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ public static partial class DismApi
/// The requested operation is successful. The DISM session needs to be reloaded.
/// </summary>
internal const int DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED = 0x00000001; // 1

/// <summary>
/// The specified package is not applicable.
/// </summary>
internal const uint CBS_E_NOT_APPLICABLE = 0x800F081E;
#pragma warning restore SA1310 // Field names must not contain underscore
}
}
11 changes: 10 additions & 1 deletion src/Microsoft.Dism/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/Microsoft.Dism/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@
<value>There are one or more open sessions.</value>
<comment>Exception message when there are one or more open sessions and a user calls the Shutdown() method.</comment>
</data>
<data name="DismExceptionMessagePackageNotApplicable" xml:space="preserve">
<value>The specified package is not applicable.</value>
<comment>Exception message when a package is not applicable.</comment>
</data>
<data name="DismExceptionMessageRebootRequired" xml:space="preserve">
<value>A restart is required to complete the operation.</value>
<comment>Exception message when an operation requires a reboot.</comment>
Expand Down

0 comments on commit c84d412

Please sign in to comment.