NullReferenceException occurs whene call EnableFeatureByPackageName

Sep 17, 2014 at 2:55 AM
I tried the code below and NullReferenceException occurred.
DismSession session = DismApi.OpenOnlineSession();
DismApi.EnableFeatureByPackageName(session, "TelnetServer", null, false, true);
In DismApi.EnableFeatureByPackageName
native DismEnableFeature function returned ERROR_SUCCESS_REBOOT_REQUIRED (3010).
Marshal.GetExceptionForHR(3010) returns null.

I think throw null causes NullReferenceException .

Nov 26, 2014 at 1:52 PM
Edited Nov 26, 2014 at 1:52 PM
I can confirm that issue. In DismApi.cs in method
private static void EnableFeature(DismSession session, string featureName, string identifier, DismPackageIdentifier packageIdentifier, bool limitAccess, bool enableAll, List<string> sourcePaths, DismProgressCallback progressCallback, object userData)
there is
if (errorCode != 0)
                throw DismException.GetDismExceptionForHR(errorCode);
I believe it should be "if (errorCode < 0)" since positive error codes mean success as well


in DismException.cs in method
internal static Exception GetDismExceptionForHR(int errorCode)
in switch statement there could be additional case for 3010 error throwing exception informing about possible reboot necessity.

Dec 1, 2014 at 6:01 PM
Yeah a return code of 3010 would definitely throw an exception. I can make one of 2 changes:
  1. Have EnableFeatureByPackageName ignore a return code of 3010
  2. Return an object indicating if a reboot is required
Ignoring the exception seems bad but is the simplest solution. Returning an object would give the caller the information that a reboot is required but would diverge this managed wrapper from the original somewhat.

What is your opinion?
Dec 3, 2014 at 1:33 PM
I think returning an object is better than ignoring a return code.
But if returning an exception with HResult is not bad manner,
I want to catch a custom exception like RebootRequiredException.
Dec 4, 2014 at 2:43 AM
Okay I created a DismRebootRequiredException that should do the trick. The caller can catch that exception and decided what to do with it.

Let me know if it doesn't work, I was only able to test it with a unit test.

Change 33528