15

I have a webapp installer that installs all of its prerequisites, which includes IIS 7 too.

Since IIS doesn't come as a prerequisite in a Visual Studio setup project, I came up with the following code to install IIS from code (targeting Windows Vista and 7).

private string ConfigureIIS7()
{
    string output = string.Empty;
    if (Environment.OSVersion.ToString().Contains("Microsoft Windows NT 5"))  // Its WindowsXP [with or without SP2]
    {
        MessageBox.Show("IIS 6.0 is not installed on this machine. Please install the same and proceed with the installation or contact your administrator","Installer",MessageBoxButtons .OK ,MessageBoxIcon .Warning);
        throw new System.Exception("IIS 6.0 is not installed on this machine.");
    }
    else
    {
        string CmdToExecute;
        CmdToExecute = "cmd /c start /w pkgmgr /l:log.etw /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ASP;IIS-CGI;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-Security;IIS-BasicAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;IIS-WebServerManagementTools;IIS-ManagementConsole;IIS-ManagementScriptingTools;IIS-ManagementService;IIS-IIS6ManagementCompatibility;IIS-Metabase;IIS-WMICompatibility;IIS-LegacyScripts;IIS-LegacySnapIn;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI";
        Process prRunIIS = new Process();
        prRunIIS.StartInfo = new ProcessStartInfo("cmd.exe", CmdToExecute);
        prRunIIS.StartInfo.UseShellExecute = false;
        prRunIIS.StartInfo.RedirectStandardOutput = true;
        prRunIIS.StartInfo.CreateNoWindow = true;
        prRunIIS.Start();
        prRunIIS.WaitForExit();
        output = prRunIIS.StandardOutput.ReadToEnd();
    }
    return output;
}

This code has worked perfectly so far. My only concern is that the installation part takes a considerable amount of time.

Now, I have the opportunity to rewrite some of the codes and alter the installer UI. I just came to this part and wondered if this was the only solution to install IIS from code, or is there may be some better way I haven't found?

I am just curious to know what are the other ways to install IIS. Answers targeted for Windows 8 are also appreciated.

3 Answers 3

12

The best option going forward is using DISM (Deployment Image Servicing and Management). This works on Windows 7/Windows server 2008 R2 and above. All other options are deprecated.

Here's a code sample with the minimum features needed (you can easily add more if you require different ones):

string SetupIIS()
{
    var featureNames = new [] 
    {
        "IIS-ApplicationDevelopment",
        "IIS-CommonHttpFeatures",
        "IIS-DefaultDocument",
        "IIS-ISAPIExtensions",
        "IIS-ISAPIFilter",
        "IIS-ManagementConsole",
        "IIS-NetFxExtensibility",
        "IIS-RequestFiltering",
        "IIS-Security",
        "IIS-StaticContent",
        "IIS-WebServer",
        "IIS-WebServerRole",
    };

    return ProcessEx.Run(
        "dism",
        string.Format(
            "/NoRestart /Online /Enable-Feature {0}",
            string.Join(
                " ", 
                featureNames.Select(name => string.Format("/FeatureName:{0}",name)))));
}           

static string Run(string fileName, string arguments)
{
    using (var process = Process.Start(new ProcessStartInfo
    {
        FileName = fileName,
        Arguments = arguments,
        CreateNoWindow = true,
        WindowStyle = ProcessWindowStyle.Hidden,
        RedirectStandardOutput = true,
        UseShellExecute = false,
    }))
    {
        process.WaitForExit();
        return process.StandardOutput.ReadToEnd();
    }
} 

This will result in the following command:

dism.exe /NoRestart /Online /Enable-Feature /FeatureName:IIS-ApplicationDevelopment /FeatureName:IIS-CommonHttpFeatures /FeatureName:IIS-DefaultDocument /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-ISAPIFilter /FeatureName:IIS-ManagementConsole /FeatureName:IIS-NetFxExtensibility /FeatureName:IIS-RequestFiltering /FeatureName:IIS-Security /FeatureName:IIS-StaticContent /FeatureName:IIS-WebServer /FeatureName:IIS-WebServerRole
Sign up to request clarification or add additional context in comments.

11 Comments

And what about getting int output? dism returns wall of text
Well if that is programmatic way, it would be convienent if result of your ProcessEx.Run() returns a code. Dism returns string right? How can I easily parse the output to know that the installation was success/failure and if failure, to get the proper error code?
@Mike That's an altogether different question. Basically it's a string, if you know what to except you can check if it's in there, but I don't really know.
Alright. Not so different :) I was looking for programmatic way to install IIS but it wasnt really reliable when the method doesn't return an error code. I guess the way to do this is to try to parse the string (if one knows its structure) or using DismAPI.dll but THAT is a different story.
@Thameem It's just the class the Run method in the post sits in. You can name it whatever you like..
|
4
+50

You have a couple options here. Pkgmgr works. You can use ServerManagerCmd.exe (Windows Server), Dism.exe (newer OSes) and leverage the flags from the MS site http://technet.microsoft.com/en-us/library/cc722041.aspx.

I would suggest threading out this component and if possible, update the UI with a progress notification/bar. That way your user will know things are progressing along.

Dism.exe is supposed to work with Windows 7, 8, 2008, etc. I would run some tests on a virgin VM with these OSes installed, take a snapshot and then run the installer. You can reapply the snapshot at will and you'll be able to test all the flags you need to make the software work.

2 Comments

Dism.exe /online /enable-feature /featurename:IIS-WebServerRole and so on
ServerManagerCmd.exe is deprecated from Windows Server 2012 onwards
3

I had a bit of issue with the proposed solution, since I was looking to install MANY more features. The application would run, and it would complete, but my application would hang waiting on the process.WaitForExit() call.

Just an FYI to anybody else out there seeking an answer. If your results output is too large, instead of process.WaitForExit(), you should run something like this:

string results = "";
while (!process.StandardOutput.EndOfStream)
{
    results += process.StandardOutput.ReadLine();
}

return results;

I needed that output in my next step, so I wrote the ReadLine() into a string that I returned.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.