Deleting ASP.NET Temporary Files on Application Restart

We load assemblies dynamically at startup and add them as a reference:

BuildManager.AddReferencedAssembly(assembly);

      

The app supports installing new plugins at runtime. Following the install / uninstall action, we restart the web application. I tried:

HostingEnvironment.InitiateShutdown();

      

and

System.Web.HttpRuntime.UnloadAppDomain();

      

However, the new version of the plugin is not loaded - I suppose this is due to the way ASP.NET aggressively caches referenced assemblies - especially ASP.NET MVC controllers.

In production this shouldn't be a problem as the build version of the plugin will increment every time. However, in development this is more of a problem as we don't want to change the version number every time we make a small change to the plugin.

How can we force asp.net temp files to be cleaned up, either programmatically or using the post build event?

One solution is to "touch" global.asax, but that seems a little hacky to me.

+3


source to share


1 answer


I used the following code snippet to reset the application pool on demand. (Just plug this into Action Controller).

Note. Since this is an application pool, you can test the impact on other applications running in the same application pool.

public class IisManager
{
    public static string GetCurrentApplicationPoolId()
    {
        // Application is not hosted on IIS
        if (!AppDomain.CurrentDomain.FriendlyName.StartsWith("/LM/"))
            return string.Empty;
        // Application hosted on IIS that doesn't support App Pools, like 5.1
        else if (!DirectoryEntry.Exists("IIS://Localhost/W3SVC/AppPools"))
            return string.Empty;

        string virtualDirPath = AppDomain.CurrentDomain.FriendlyName;
        virtualDirPath = virtualDirPath.Substring(4);
        int index = virtualDirPath.Length + 1;
        index = virtualDirPath.LastIndexOf("-", index - 1, index - 1);
        index = virtualDirPath.LastIndexOf("-", index - 1, index - 1);
        virtualDirPath = "IIS://localhost/" + virtualDirPath.Remove(index);
        var virtualDirEntry = new DirectoryEntry(virtualDirPath);
        return virtualDirEntry.Properties["AppPoolId"].Value.ToString();
    }


    public static void RecycleApplicationPool(string appPoolId)
    {
        string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPoolId;
        var appPoolEntry = new DirectoryEntry(appPoolPath);
        appPoolEntry.Invoke("Recycle");
    }

    public static void RecycleApplicationPool(string appPoolId, string username, string password)
    {
        string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPoolId;
        var appPoolEntry = new DirectoryEntry(appPoolPath, username, password);
        appPoolEntry.Invoke("Recycle");
    }

}

      



The overridden method is for cases where you want to explicitly pass a user with administrator privileges on the machine / server that hosts the IIS instance.

And the controller action could be something like:

 public string ResetAppPool()
    {
        var appPoolId = IisManager.GetCurrentApplicationPoolId();
        if (appPoolId.Equals(string.Empty))
            return "Application is not running inside an App Pool"; //May be not IIS 6 onwards
        try
        {
            IisManager.RecycleApplicationPool(appPoolId); //Can only be used by Admin users
            return string.Format("App pool {0} recycled successfully", appPoolId);
        }
        catch (Exception ex)
        {
            Logger.Error("Failed to recycle app pool : " + ex.StackTrace);
            return string.Format("App pool {0} recycle failed", appPoolId);
        }
    }

      

+1


source







All Articles