Better way to install IIS7 programmatically
Asked Answered
S

3

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.

Segment answered 18/4, 2013 at 9:19 Comment(0)
H
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
Halhalafian answered 30/7, 2014 at 21:52 Comment(11)
And what about getting int output? dism returns wall of textStarlight
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?Starlight
@Starlight 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.Halhalafian
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.Starlight
For me this works fine in Win 7 and Win 8.1 machines. But not working on Windows Server 2008 R2 and Windows Server 2012 R2.Mitziemitzl
@Halhalafian When web server (IIS) not selected on the server machines I want this code should enable web server (IIS) and its additonal features such as ASP.NET. In win 7 and win 8.1 machine if Internet information options is not selected this code enables it and also adds addtional features we specify in the array. Same not working in server machines.Mitziemitzl
I have added my sample #16079530Mitziemitzl
@Halhalafian In win 7 and win 8.1 machines it is working fine. In server 2008 R2 and Server 2012 R2 not working even if I run my sample app as administrator. One thing I observed is if I open the CMD in the server machine as administrator and run the command manually it works.Mitziemitzl
I am getting error in ProcessEx. The name ProcessEx does not exist ? Is it a variable or a keyword ? how to correct this ?Cremate
@Cremate It's just the class the Run method in the post sits in. You can name it whatever you like..Halhalafian
@Halhalafian oops..okCremate
M
4

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.

Malayoindonesian answered 24/4, 2013 at 19:6 Comment(2)
Dism.exe /online /enable-feature /featurename:IIS-WebServerRole and so onMalayoindonesian
ServerManagerCmd.exe is deprecated from Windows Server 2012 onwardsLonglived
E
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.

Esquivel answered 20/10, 2015 at 0:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.