简体   繁体   English

以编程方式安装IIS7的更好方法

[英]Better way to install IIS7 programmatically

I have a webapp installer that installs all of its prerequisites, which includes IIS 7 too. 我有一个webapp安装程序,可以安装所有必备软件,其中包括IIS 7。

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). 由于IIS不是Visual Studio安装项目的先决条件,因此我提出了以下代码来从代码安装IIS(针对Windows Vista和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. 现在,我有机会重写一些代码并更改安装程序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? 我刚刚来到这一部分并想知道这是否是从代码安装IIS的唯一解决方案,还是可能有一些更好的方法我没有找到?

I am just curious to know what are the other ways to install IIS. 我只是想知道安装IIS的其他方法是什么。 Answers targeted for Windows 8 are also appreciated. 针对Windows 8的答案也很受欢迎。

The best option going forward is using DISM (Deployment Image Servicing and Management). 未来最好的选择是使用DISM (部署映像服务和管理)。 This works on Windows 7 / Windows server 2008 R2 and above. 这适用于Windows 7 / Windows server 2008 R2及更高版本。 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. Pkgmgr有效。 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 . 您可以使用ServerManagerCmd.exe(Windows Server),Dism.exe(较新的操作系统)并利用MS站点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. 我建议线程化这个组件,如果可能的话,用进度通知/栏更新UI。 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. Dism.exe应该适用于Windows 7,8,2008等。我会在安装了这些操作系统的原始虚拟机上运行一些测试,拍摄快照然后运行安装程序。 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. 应用程序将运行,它将完成,但我的应用程序将等待process.WaitForExit()调用。

Just an FYI to anybody else out there seeking an answer. 只是一个FYI给那里的其他人寻求答案。 If your results output is too large, instead of process.WaitForExit() , you should run something like this: 如果你的结果输出太大,而不是process.WaitForExit() ,你应该运行这样的东西:

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. 我在下一步中需要输出,所以我将ReadLine()写入我返回的字符串中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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