重新启动(回收)应用程序池

本文关键字:应用程序 程序池 应用 回收 重新启动 | 更新日期: 2023-09-27 17:47:46

如何从 C# (.net 2( 重新启动(回收(IIS 应用程序池?

如果您发布示例代码,请表示感谢?

重新启动(回收)应用程序池

我们来了:

HttpRuntime.UnloadAppDomain();

如果您使用的是 IIS7,那么如果它停止,这将完成。 我假设您可以调整重新启动而无需显示。

// Gets the application pool collection from the server.
[ModuleServiceMethod(PassThrough = true)]
public ArrayList GetApplicationPoolCollection()
{
    // Use an ArrayList to transfer objects to the client.
    ArrayList arrayOfApplicationBags = new ArrayList();
    ServerManager serverManager = new ServerManager();
    ApplicationPoolCollection applicationPoolCollection = serverManager.ApplicationPools;
    foreach (ApplicationPool applicationPool in applicationPoolCollection)
    {
        PropertyBag applicationPoolBag = new PropertyBag();
        applicationPoolBag[ServerManagerDemoGlobals.ApplicationPoolArray] = applicationPool;
        arrayOfApplicationBags.Add(applicationPoolBag);
        // If the applicationPool is stopped, restart it.
        if (applicationPool.State == ObjectState.Stopped)
        {
            applicationPool.Start();
        }
    }
    // CommitChanges to persist the changes to the ApplicationHost.config.
    serverManager.CommitChanges();
    return arrayOfApplicationBags;
}

如果你在IIS6上,我不太确定,但你可以尝试获取web.config并编辑修改日期或其他东西。 对 web.config 进行编辑后,应用程序将重新启动。

测试以下方法适用于 IIS7 和 IIS8

步骤 1 :添加对 Microsoft.Web.Administration.dll 的引用。该文件可以在路径 C:''Windows''System32''inetsrv'' 中找到,或将其安装为 NuGet 包 https://www.nuget.org/packages/Microsoft.Web.Administration/

第 2 步:添加以下代码

using Microsoft.Web.Administration;

使用空条件运算符

new ServerManager().ApplicationPools["Your_App_Pool_Name"]?.Recycle();

使用 if 条件检查空

var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
    yourAppPool.Recycle();

也许这篇文章会有所帮助:

  • 以编程方式回收当前应用程序池(对于 IIS 6+(
  • 在 IIS 6.0 中使用 WMI 回收应用程序池
  • 以编程方式回收 IIS 6.0 应用程序池
  • 以编程方式回收 IIS 应用程序池

下面的代码适用于 IIS6。未在 IIS7 中测试。

using System.DirectoryServices;
...
void Recycle(string appPool)
{
    string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPool;
    using (DirectoryEntry appPoolEntry = new DirectoryEntry(appPoolPath))
    {
            appPoolEntry.Invoke("Recycle", null);
            appPoolEntry.Close();
    }
}

您也可以将"回收"更改为"开始"或"停止"。

我用我的代码走了一条稍微不同的路线来回收应用程序池。 需要注意的几点与其他人提供的有所不同:

1( 我使用 using 语句来确保正确处置 ServerManager 对象。

2( 我正在等待应用程序池在停止之前完成启动,这样我们就不会在尝试停止应用程序时遇到任何问题。 同样,我正在等待应用程序池完成停止,然后再尝试启动它。

3(我强制该方法接受实际的服务器名称,而不是回退到本地服务器,因为我认为您可能应该知道您正在针对哪个服务器运行此服务器。

4( 我决定启动/停止应用程序,而不是回收它,这样我就可以确保我们不会意外启动因其他原因而停止的应用程序池,并避免尝试回收已停止的应用程序池时出现问题。

public static void RecycleApplicationPool(string serverName, string appPoolName)
{
    if (!string.IsNullOrEmpty(serverName) && !string.IsNullOrEmpty(appPoolName))
    {
        try
        {
            using (ServerManager manager = ServerManager.OpenRemote(serverName))
            {
                ApplicationPool appPool = manager.ApplicationPools.FirstOrDefault(ap => ap.Name == appPoolName);
                //Don't bother trying to recycle if we don't have an app pool
                if (appPool != null)
                {
                    //Get the current state of the app pool
                    bool appPoolRunning = appPool.State == ObjectState.Started || appPool.State == ObjectState.Starting;
                    bool appPoolStopped = appPool.State == ObjectState.Stopped || appPool.State == ObjectState.Stopping;
                    //The app pool is running, so stop it first.
                    if (appPoolRunning)
                    {
                        //Wait for the app to finish before trying to stop
                        while (appPool.State == ObjectState.Starting) { System.Threading.Thread.Sleep(1000); }
                        //Stop the app if it isn't already stopped
                        if (appPool.State != ObjectState.Stopped)
                        {
                            appPool.Stop();
                        }
                        appPoolStopped = true;
                    }
                    //Only try restart the app pool if it was running in the first place, because there may be a reason it was not started.
                    if (appPoolStopped && appPoolRunning)
                    {
                        //Wait for the app to finish before trying to start
                        while (appPool.State == ObjectState.Stopping) { System.Threading.Thread.Sleep(1000); }
                        //Start the app
                        appPool.Start();
                    }
                }
                else
                {
                    throw new Exception(string.Format("An Application Pool does not exist with the name {0}.{1}", serverName, appPoolName));
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception(string.Format("Unable to restart the application pools for {0}.{1}", serverName, appPoolName), ex.InnerException);
        }
    }
}

在 IIS6 上工作的回收代码:

    /// <summary>
    /// Get a list of available Application Pools
    /// </summary>
    /// <returns></returns>
    public static List<string> HentAppPools() {
        List<string> list = new List<string>();
        DirectoryEntry W3SVC = new DirectoryEntry("IIS://LocalHost/w3svc", "", "");
        foreach (DirectoryEntry Site in W3SVC.Children) {
            if (Site.Name == "AppPools") {
                foreach (DirectoryEntry child in Site.Children) {
                    list.Add(child.Name);
                }
            }
        }
        return list;
    }
    /// <summary>
    /// Recycle an application pool
    /// </summary>
    /// <param name="IIsApplicationPool"></param>
    public static void RecycleAppPool(string IIsApplicationPool) {
        ManagementScope scope = new ManagementScope(@"''localhost'root'MicrosoftIISv2");
        scope.Connect();
        ManagementObject appPool = new ManagementObject(scope, new ManagementPath("IIsApplicationPool.Name='W3SVC/AppPools/" + IIsApplicationPool + "'"), null);
        appPool.InvokeMethod("Recycle", null, null);
    }

有时我觉得简单是最好的。虽然我建议人们以某种聪明的方式调整实际路径,以在其他环境中以更广泛的方式工作 - 我的解决方案如下所示:

ExecuteDosCommand(@"c:'Windows'System32'inetsrv'appcmd recycle apppool " + appPool);

从 C# 中,运行一个可以解决问题的 DOS 命令。上述许多解决方案不适用于各种设置和/或需要打开 Windows 上的功能(取决于设置(。

这段代码对我有用。 只需调用它即可重新加载应用程序。

System.Web.HttpRuntime.UnloadAppDomain()

如果您只想回收当前计算机上的所有应用程序池,这里有一个简单的解决方案。我必须"以管理员身份运行"才能正常工作。

using (var serverManager = new ServerManager())
{
    foreach (var appPool in serverManager.ApplicationPools)
    {
        appPool.Recycle();
    }
}

另一种选择:

System.Web.Hosting.HostingEnvironment.InitiateShutdown();

似乎比UploadAppDomain更好,后者在前者等待内容完成其工作时"终止"应用程序。