简体   繁体   中英

Better way to install IIS7 programmatically

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.

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM