【问题标题】:Restarting (Recycling) an Application Pool重新启动(回收)应用程序池
【发布时间】:2010-09-19 23:30:36
【问题描述】:

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

如果您发布示例代码,请欣赏?

【问题讨论】:

    标签: c# .net asp.net-mvc iis application-pool


    【解决方案1】:

    我们开始吧:

    HttpRuntime.UnloadAppDomain();
    

    【讨论】:

    • 这会回收应用程序,但我不确定它会回收整个应用程序池(可以同时托管多个应用程序)。
    • @Marc - 非常有效,尽管有时您只关心当前的应用程序上下文。表明需要重新加载的条件可以在每个实例中独立声明。
    • 非常有帮助,我一直需要这个! (我只在当前上下文中需要它)
    • +1 我很好奇,为什么有人要回收他的应用程序?我的意思是什么是场景(我是 asp.net)开发人员。
    • 如果您需要远程回收您的网络应用程序(例如长期/单例对象行为不端),这非常有用
    【解决方案2】:

    如果您在 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 进行编辑后,应用程序将重新启动。

    【讨论】:

    • 哦,继续告诉他如何调整重启。你知道怎么做吗?
    • +1 你就是那个男人。经过不少于 10 个解决方案(包括触摸 web.config),这就是胜利。
    • 嗨,这是一篇非常古老的帖子,但我正在努力找出其中的一部分。 “ServerManagerDemoGlobals.ApplicationPoolArray”从何而来?即我应该参考什么来访问它?我添加了对 Microsoft.Web.Management.dll 和 Microsoft.Web.Administration.dll 的引用,谢谢
    • @Jon 我也遇到了这个问题。
    • 我添加了对此的引用,它满足属性和 propertyBag c:\windows\SysWOW64\inetsrv\Microsoft.Web.Management.dll(也可以在 c:\windows\system32\inetsrv\ Microsoft.Web.Management.dll)
    【解决方案3】:
    【解决方案4】:

    下面的代码适用于 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();
        }
    }
    

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

    【讨论】:

    • 请注意,您需要在 IIS7 上启用“IIS 6 WMI 兼容性”
    【解决方案5】:

    我的代码采用了稍微不同的方法来回收应用程序池。需要注意的几点与其他人提供的不同:

    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);
            }
        }
    }
    

    【讨论】:

    • 在我的 iis8 上运行良好,没有错误只需要添加提到的参考 Microsoft.Web.Administration。
    【解决方案6】:

    以下方法经测试适用于 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 条件检查 null

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

    【讨论】:

      【解决方案7】:

      回收在 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);
          }
      

      【讨论】:

        【解决方案8】:

        有时我觉得简单是最好的。虽然我建议以某种巧妙的方式调整实际路径,以在其他环境中以更广泛的方式工作 - 我的解决方案看起来像:

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

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

        【讨论】:

        • 这尤其是如果您在尝试其他解决方案之一时遇到未知错误 0x80005000。各有各的好处。
        • 我推荐这个关于如何制作自己的“ExecuteDosCommand”方法。 codeproject.com/Articles/25983/How-to-Execute-a-Command-in-C
        • 如果您在远程服务器上运行上述命令,您将如何运行它?
        • 这个对我来说效果最好。除了我打了 2 个电话:在回收时停止并开始
        【解决方案9】:

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

        System.Web.HttpRuntime.UnloadAppDomain()
        

        【讨论】:

          【解决方案10】:

          另一种选择:

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

          似乎比 UploadAppDomain 更好,后者“终止”应用程序,而前者等待工作完成。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-16
            • 2011-05-05
            • 2010-09-28
            • 1970-01-01
            • 2012-03-28
            • 2011-10-17
            相关资源
            最近更新 更多