Anti-virus scans the .Net deployed folders. Because of this, application gets logged out frequently for the customers.
Requires lot of approval in order to get exemption at the folder level for the project. So, I used below code:
//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[] { });
Used this article for above code.
Code works fine for a day. But, problem starts again next day. So, I replace the deployed folder again. Then, everything works fine.
Would like to know what causes the problem starts again. What should be done to not face again.
Also, how to stop scanning all the folders where application deployed. Because, application has custom folders where output files will be saved. This also should not be scanned.
Thanks in advance!
This is because you have your app pool being recycled by IIS (which is a good thing, because it will prevent any memory leaks you might have).
When this happens, Application_start
is no longer called: https://msdn.microsoft.com/en-us/library/ms178473.aspx (same applies for IIS 7.0+)
What you should do is set up a static
field in your Global.asax
and on each Application_AcquireRequestState
check if it is set to true
. if not, run the code you posted, and then set the field to true.
This will ensure that the code will only ever run once per your worker process being alive.
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;
}
}
Since there are only 2 monitors inside the FileChangesMonitor
class, you simply need to stop monitoring on both, so the full listing would be:
// 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;
}
}
Thanks a lot to @zaitsman for his help
With his help, modified the code like below
<%@ 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;
}
}
Hope code would help someone
However, I initially received null error when accessing monitor_dirMonAppPathInternal
object. If anyone could say when the object will not be null, it would be helpful