在asp.net中关闭Global.asax中的文件/文件夹更改

时间:2017-11-08 06:16:29

标签: c# asp.net iis iis-7 global-asax

防病毒扫描.Net部署的文件夹。因此,应用程序会经常为客户注销。

需要大量批准才能在项目的文件夹级别获得豁免。所以,我使用下面的代码:

//FIX disable AppDomain restart when deleting subdirectory
//This code will turn off monitoring from the root website directory.
//Monitoring of Bin, App_Themes and other folders will still be operational, so updated DLLs will still auto deploy.
System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

object o = p.GetValue(null, null);
System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);

object monitor = f.GetValue(o);
System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { }); 

在上面的代码中使用了这篇文章。

代码正常工作一天。但是,问题第二天又开始了。所以,我再次替换部署的文件夹。然后,一切正常。

想知道导致问题再次出现的原因。不应该再做什么应该做什么。

此外,如何停止扫描部署应用程序的所有文件夹。因为,应用程序具有将保存输出文件的自定义文件夹。这也不应该被扫描。

提前致谢!

2 个答案:

答案 0 :(得分:0)

这是因为你的应用程序池被IIS回收(这是一件好事,因为它可以防止你可能有任何内存泄漏)。

发生这种情况时,不再调用Application_starthttps://msdn.microsoft.com/en-us/library/ms178473.aspx(同样适用于IIS 7.0 +)

您应该在static和每个Global.asax检查中设置一个Application_AcquireRequestState字段,检查它是否设置为true。如果没有,请运行您发布的代码,然后将该字段设置为true。

这将确保代码只会在您的工作进程处于活动状态时运行一次。

private static bool hasRemovedFoldersFromMonitoring = false;

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if(!hasRemovedFoldersFromMonitoring){
        System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

        object o = p.GetValue(null, null);
        System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);

        object monitor = f.GetValue(o);
        System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { }); 
        hasRemovedFoldersFromMonitoring = true;
    }
}

由于FileChangesMonitor类中只有2个监视器,您只需要停止监视两者,因此完整列表将是:

// Add at the top of the file
using System.Reflection;

// anywhere
private static bool hasRemovedFoldersFromMonitoring = false;

private void StopMonitoring(FileChangesMonitor fcm, string monitorName)
{
 var f = typeof(FileChangesMonitor).GetField(monitorName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);

        var monitor = f.GetValue(fcm);
        var m = monitor.GetType().GetMethod("StopMonitoring", BindingFlags.Instance |BindingFlags.NonPublic); 
        m.Invoke(monitor, new object[] { }); 
}

protected void Application_AcquireRequestState(object sender, EventArgs e)
{

    if(!hasRemovedFoldersFromMonitoring){
        var fcmPi = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

        var fcm = (FileChangesMonitor)fcmPi .GetValue(null, null);

        this.StopMonitoring(fcm, "_dirMonSubdirs");
        this.StopMonitoring(fcm, "_dirMonAppPathInternal");

        hasRemovedFoldersFromMonitoring = true;
    }
}

答案 1 :(得分:0)

非常感谢@zaitsman的帮助

在他的帮助下,修改了下面的代码

<%@ import namespace="System.Reflection"%>
private static bool hasRemovedFoldersFromMonitoring = false;
protected void Application_AcquireRequestState(object sender, EventArgs e)
{

    if (!hasRemovedFoldersFromMonitoring)
    {           

        PropertyInfo fcmPi = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
        object o = fcmPi.GetValue(null, null);

        FieldInfo fi_dirMonSubdirs = o.GetType().GetField("_dirMonSubdirs", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
        object monitor_dirMonSubdirs = fi_dirMonSubdirs.GetValue(o);

        MethodInfo m_dirMonSubdirs = monitor_dirMonSubdirs.GetType().GetMethod("StopMonitoring", BindingFlags.Instance | BindingFlags.NonPublic);
        m_dirMonSubdirs.Invoke(monitor_dirMonSubdirs, new object[] { });

        FieldInfo fi_dirMonAppPathInternal = o.GetType().GetField("_dirMonAppPathInternal", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
        object monitor_dirMonAppPathInternal = fi_dirMonAppPathInternal.GetValue(o);

        if (monitor_dirMonAppPathInternal != null)
        {
            MethodInfo m_dirMonAppPathInternal = monitor_dirMonAppPathInternal.GetType().GetMethod("StopMonitoring", BindingFlags.Instance | BindingFlags.NonPublic);
            m_dirMonAppPathInternal.Invoke(monitor_dirMonAppPathInternal, new object[] { });
        }
        hasRemovedFoldersFromMonitoring = true;
    }
}

希望代码可以帮助某人

但是,我最初在访问monitor_dirMonAppPathInternal对象时收到null错误。如果有人可以说对象何时不为null,那将会很有帮助