Introduction
My earlier article [^] on detecting what .NET Framework versions and service packs are installed using managed code generated some follow up questions related to detecting if Internet Information Services (IIS) is installed and if ASP or ASP.NET is registered.
Since this is a managed code solution, it does require that a version of the .NET Framework is already installed, so this class is not guaranteed to work as part of an installation process. If you need to do this reliably from an installation process, you need to look at doing the same work using unmanaged C++.
Background
The correct way to determine if a specific version of Internet Information Services is installed is to look in the registry for the following key:
HKLM\Software\Microsoft\InetStp\MajorVersion
This is a DWORD value that indicates the version of IIS installed, if it exists.
MajorVersion |
IIS Version |
Description |
4 |
IIS 4 |
Shipped in NT Option Pack for Windows NT 4 |
5 |
IIS 5 |
Shipped in Windows 2000 Server and Windows XP Professional |
6 |
IIS 6 |
Shipped in Windows Server 2003 |
7 |
IIS 7 |
Shipped in Windows Vista |
For IIS 5, you can use the MinorVersion DWORD value to determine if you are running on Windows 2000 Server or Windows XP Professional. If MinorVersion is 1, then you are running on Windows XP Professional.
Detecting IIS Subcomponents
Sometimes, just knowing if IIS is installed isn't enough and you need to determine if specific subcomponents are also installed. Again, we can turn to the registry for this information. All of the subcomponent information is contained in the following registry key:
HKLM\Software\Microsoft\Microsoft\Windows\CurrentVersion\Setup\Oc Manager\Subcomponents
All of the values under this key are DWORDs, so if the value is 1 then that component is installed.
IIS Subcomponent |
Registry value |
IIS common files |
iis_common |
Active Server Pages (ASP) for IIS |
iis_asp |
File Transfer Protocol (FTP) service |
iis_ftp |
IIS Manager (Microsoft Management Console [MMC] snap-in) |
iis_inetmgr |
Internet Data Connector |
iis_internetdataconnector |
Network News Transfer Protocol (NNTP) service |
iis_nntp |
Server-Side Includes |
iis_serversideincludes |
Simple Mail Transfer Protocol (SMTP) service |
iis_smtp |
Web Distributed Authoring and Versioning (WebDAV) publishing |
iis_webdav |
World Wide Web (WWW) service |
iis_www |
Remote administration (HTML) |
sakit_web |
Internet Server Application Programming Interface (ISAPI) for Background Intelligent Transfer Service (BITS) server extensions |
BitsServerExtensionsISAPI |
Background Intelligent Transfer Service (BITS) server extensions snap-in |
BitsServerExtensionsManager |
FrontPage server extensions |
fp_extensions |
Internet printing |
inetprint |
ActiveX control and sample pages for hosting Terminal Services client connections over the Web |
TSWebClient |
Detecting if ASP or ASP.NET is Registered
In order to detect if ASP is registered with IIS, you can simply look to see if the ASP component (iis_asp) is installed. However, for ASP.NET it becomes a little bit more involved since there are different versions of ASP.NET. We can also use the registry for this information, by looking at the following keys:
Framework Version |
Registry Key |
ASP.NET v1.1 |
HKLM\Software\Microsoft\ASP.NET\1.1.4322.0 |
ASP.NET v2.0 |
HKLM\Software\Microsoft\ASP.NET\2.0.50727.0 |
If the key exists, then that version of ASP.NET is registered with IIS.
Using the Code
In order to consolidate checking all of the various registry keys and help isolate changes for future versions of the .NET Framework and IIS, the InternetInformationServicesDetection
class was created. This class exposes the following public
methods:
-
public static bool IsInstalled(InternetInformationServicesVersion iisVersion)
-
public static bool IsInstalled(InternetInformationServicesComponent subcomponent)
-
public static bool IsAspRegistered()
-
public static bool IsAspNetRegistered(FrameworkVersion frameworkVersion)
As you can see, these functions use the FrameworkVersion
, InternetInformationServicesVersion
, and InternetInformationServicesComponent
enumerations. These enumerations have the following definition:
public enum FrameworkVersion
{
Fx10,
Fx11,
Fx20,
Fx30,
Fx35,
}
public enum InternetInformationServicesVersion
{
IIS4,
IIS5,
IIS6,
IIS7,
}
public enum InternetInformationServicesComponent
{
Common,
ASP,
FTP,
InetMgr,
InternetDataConnector,
NNTP,
ServerSideIncludes,
SMTP,
WebDAV,
WWW,
RemoteAdmin,
BitsISAPI,
Bits,
FrontPageExtensions,
InternetPrinting,
TSWebClient,
}
A complete example in C# looks like this:
bool iis4Installed =
InternetInformationServicesDetection.IsInstalled
(InternetInformationServicesVersion.IIS4);
bool iis5Installed =
InternetInformationServicesDetection.IsInstalled
(InternetInformationServicesVersion.IIS5);
bool iis6Installed =
InternetInformationServicesDetection.IsInstalled
(InternetInformationServicesVersion.IIS6);
bool iis7Installed =
InternetInformationServicesDetection.IsInstalled
(InternetInformationServicesVersion.IIS7);
Console.WriteLine("IIS 4 installed? {0}", iis4Installed);
Console.WriteLine("IIS 5 installed? {0}", iis5Installed);
Console.WriteLine("IIS 6 installed? {0}", iis6Installed);
Console.WriteLine("IIS 7 installed? {0}", iis7Installed);
if (iis4Installed || iis5Installed || iis6Installed || iis7Installed)
{
Console.WriteLine("ASP Registered? {0}",
InternetInformationServicesDetection.IsAspRegistered());
Console.WriteLine("ASP.NET 1.0 Registered? {0}",
InternetInformationServicesDetection.IsAspNetRegistered(FrameworkVersion.Fx10));
Console.WriteLine("ASP.NET 1.1 Registered? {0}",
InternetInformationServicesDetection.IsAspNetRegistered(FrameworkVersion.Fx11));
Console.WriteLine("ASP.NET 2.0 Registered? {0}",
InternetInformationServicesDetection.IsAspNetRegistered(FrameworkVersion.Fx20));
Console.WriteLine("ASP.NET 3.0 Registered? {0}",
InternetInformationServicesDetection.IsAspNetRegistered(FrameworkVersion.Fx30));
Console.WriteLine("ASP.NET 3.5 Registered? {0}",
InternetInformationServicesDetection.IsAspNetRegistered(FrameworkVersion.Fx35));
}
Points of Interest
The public
methods are simply wrappers that determine which private
function should be called. These private
functions, in turn, query the appropriate registry keys and process the result. However, the real work is done in the GetRegistryValue<T>
function. This is a generic function that returns a boolean
value indicating if the requested registry key was found and an out
parameter that contains the value.
It is important to note that if the user does not have the appropriate permissions to access the registry, this function will throw an exception that will bubble up to the original caller. This was intentionally done to allow the caller the ability to take different actions based on the exception thrown.
Future Considerations
Windows XP 64-bit and Windows Vista 64-bit support. If someone wants to test this on these operating systems and let me know if it runs properly and if not what the errors are, I will correct them.
History
- 6-April-2007
- 17-August-2007
- Updated the download to include fixes to the
FrameworkVersionDetection
class for the .NET Framework v3.5 Beta 2