Detecting Server Core in Code

Administrators can move between Server Core and Server with a GUI by installing or uninstalling various features, so it's important that applications designed for Server Core are able to react and behave appropriately whether running in Server Core or Server with a GUI. One way of doing this is by dynamically loading dependent libraries (for example, using LoadLibrary or LoadLibraryEx instead of static import libraries) and modifying your application's behavior if a required dependency isn't found.

 

Another way is by checking for the installation state of various Windows features and modifying your application's behavior accordingly. We make this possible through the public Dism APIs.

 

Here is some sample C++ code. It won't compile straight away, but reading over this code snippet should give you an idea about how you can check for Server Core.

 

What the code does

The code calls the Dism API to check the installation state of a Windows feature.

 

How to use it

  1. Determine which functionalities of your app are not available in Server Core. Features that are not available in Server Core include MMC, Internet Explorer, MSHTML, and many GUI libraries such as HTML Help and WPF. Locate the FeatureNames of those features by calling dism /online /get-features from a command prompt.
  2. Complete the TODO: block with your own logic that should execute when the features you selected in the previous step are not installed.
  3. Optionally, add additional cases to check for the other installation states. The code checks only for "Disabled with Payload Removed" state. Other states are discussed on the MSDN documentation (link below).

 

Code sample

 

HRESULT CheckFeatureState ( _featureName ) {

   

    // Call to get feature info from Dism API:

    hr = DismGetFeatureInfo ( session , _featureName , NULL , DismPackageNone , & featureInfo );

   

    if ( S_OK != hr ) {

        Log :: Error ( L"DismGetFeatureInfo failed with error code: %d" )

        return hr ;

    }

    if ( featureInfo -> FeatureState != DismStateRemoved ) {            

        

        // Feature is "Disabled with payload removed"

        // TODO: Adapt app logic here or return appropriate value

       

     }                                                                  

    hr = DismDelete ( featureInfo );   // free memory allocated by DismGetFeatureInfo.

    if ( S_OK != hr ) {

        Log :: Error ( L"DismDelete failed with error code: %d" );

        return hr ;

    }

    featureInfo = NULL ;

    return hr ;  

}  

 

You can read more about the Dism API on MSDN: https://msdn.microsoft.com/library/windows/desktop/hh824738.aspx

 

Thanks for supporting Server Core through your development efforts!

 

The Server Core Team