/// <summary>
        /// ISU and internal use only.
        /// </summary>
        public static void StopIisAppPool(string name)
        {
            executeInIisServerManagerTransaction(
                () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
                    false,
                    (serverManager, enumGetter) => {
                var pool = serverManager.ApplicationPools[name];
                if (pool != null)
                {
                    // Stop throws an exception if the pool isn't started.
                    if (pool.State != enumGetter("Microsoft.Web.Administration.ObjectState", "Stopped") &&
                        pool.State != enumGetter("Microsoft.Web.Administration.ObjectState", "Stopping"))
                    {
                        pool.Stop();
                    }

                    while (pool.State != enumGetter("Microsoft.Web.Administration.ObjectState", "Stopped"))
                    {
                        Thread.Sleep(1000);
                    }

                    pool.AutoStart = false;
                }
            }));
        }
 /// <summary>
 /// ISU and internal use only.
 /// </summary>
 public static void UpdateIisAppPool(string name)
 {
     executeInIisServerManagerTransaction(
         () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
             false,
             (serverManager, enumGetter) => {
         var pool       = serverManager.ApplicationPools[name] ?? serverManager.ApplicationPools.Add(name);
         pool.AutoStart = false;
     }));
 }
 /// <summary>
 /// ISU and internal use only.
 /// </summary>
 public static void DeleteIisAppPool(string name)
 {
     executeInIisServerManagerTransaction(
         () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
             false,
             (serverManager, enumGetter) => {
         var pool = serverManager.ApplicationPools[name];
         if (pool != null)
         {
             serverManager.ApplicationPools.Remove(pool);
         }
     }));
 }
 /// <summary>
 /// ISU and internal use only.
 /// </summary>
 public static void DeleteIisSite(string name)
 {
     executeInIisServerManagerTransaction(
         () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
             false,
             (serverManager, enumGetter) => {
         var site = serverManager.Sites[name];
         if (site != null)
         {
             serverManager.Sites.Remove(site);
         }
     }));
 }
        /// <summary>
        /// ISU and internal use only.
        /// </summary>
        public static void DeleteIisVirtualDirectory(string site, string name)
        {
            executeInIisServerManagerTransaction(
                () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
                    false,
                    (serverManager, enumGetter) => {
                var iisSite = serverManager.Sites[site];

                var path = "/{0}".FormatWith(name);
                var app  = iisSite.Applications[path];
                if (app != null)
                {
                    iisSite.Applications.Remove(app);
                }
            }));
        }
        /// <summary>
        /// ISU and internal use only.
        /// </summary>
        public static void StartIisAppPool(string name)
        {
            executeInIisServerManagerTransaction(
                () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
                    false,
                    (serverManager, enumGetter) => {
                var pool = serverManager.ApplicationPools[name];
                pool.Start();
                while (pool.State != enumGetter("Microsoft.Web.Administration.ObjectState", "Started"))
                {
                    Thread.Sleep(1000);
                }

                pool.AutoStart = true;
            }));
        }
        /// <summary>
        /// ISU and internal use only.
        /// </summary>
        public static void UpdateIisVirtualDirectory(string site, string name, string appPool, string physicalPath)
        {
            executeInIisServerManagerTransaction(
                () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
                    false,
                    (serverManager, enumGetter) => {
                var iisSite = serverManager.Sites[site];

                var path = "/{0}".FormatWith(name);
                var app  = iisSite.Applications[path] ?? iisSite.Applications.Add(path, physicalPath);
                app.ApplicationPoolName = appPool;
                app["preloadEnabled"]   = true;

                var rootVd          = app.VirtualDirectories["/"];
                rootVd.PhysicalPath = physicalPath;
            }));
        }
 /// <summary>
 /// Standard Library and RSIS use only.
 /// </summary>
 public static void ConfigureIis(bool iisExpress)
 {
     // Overlapping commitment of changes to server manager do not end well.
     AppTools.ExecuteAsCriticalRegion(
         "{1BC5B312-F0F0-11DF-B6B9-118ADFD72085}",
         false,
         delegate {
         try {
             IisConfigurationStatics.ConfigureIis(iisExpress);
         }
         catch (Exception e) {
             const string message = "Failed to configure IIS.";
             if (e is UnauthorizedAccessException)
             {
                 throw new UserCorrectableException(message, e);
             }
             throw new ApplicationException(message, e);
         }
     });
 }
        private static void configureIis(bool iisExpress, bool useServerAppPoolSettings)
        {
            IisConfigurationStatics.ExecuteInServerManagerTransaction(
                iisExpress,
                (serverManager, enumGetter) => {
                if (!iisExpress)
                {
                    var poolDefaults       = serverManager.ApplicationPoolDefaults;
                    poolDefaults.StartMode = enumGetter("Microsoft.Web.Administration.StartMode", useServerAppPoolSettings ? "AlwaysRunning" : "OnDemand");

                    // We use this because it's a consistent account name across all machines, which allows our SQL Server databases [which must grant access to the
                    // app pool] to be portable.
                    poolDefaults.ProcessModel.IdentityType = enumGetter("Microsoft.Web.Administration.ProcessModelIdentityType", "NetworkService");

                    // Disable idle time-out.
                    poolDefaults.ProcessModel.IdleTimeout = useServerAppPoolSettings ? TimeSpan.Zero : new TimeSpan(0, 5, 0);

                    // Disable regular time interval recycling.
                    poolDefaults.Recycling.PeriodicRestart.Time = TimeSpan.Zero;

                    poolDefaults.Recycling.PeriodicRestart.Schedule.Clear();
                    if (useServerAppPoolSettings)
                    {
                        poolDefaults.Recycling.PeriodicRestart.Schedule.Add(new TimeSpan(23, 55, 0));
                    }
                }

                var config = serverManager.GetApplicationHostConfiguration();

                var modulesSection = config.GetSection("system.webServer/modules", "");
                foreach (var element in modulesSection.GetCollection())
                {
                    element.SetMetadata("lockItem", null);
                }

                var serverRuntimeSection          = config.GetSection("system.webServer/serverRuntime", "");
                serverRuntimeSection.OverrideMode = enumGetter("Microsoft.Web.Administration.OverrideMode", "Allow");
            });
        }
        /// <summary>
        /// ISU and internal use only.
        /// </summary>
        public static void UpdateIisSite(string name, string appPool, string physicalPath, IReadOnlyCollection <IisHostName> hostNames)
        {
            executeInIisServerManagerTransaction(
                () => IisConfigurationStatics.ExecuteInServerManagerTransaction(
                    false,
                    (serverManager, enumGetter) => {
                const int dummyPort = 80;
                var site            = serverManager.Sites[name] ?? serverManager.Sites.Add(name, physicalPath, dummyPort);

                var rootApp = site.Applications["/"];
                rootApp.ApplicationPoolName = appPool;
                rootApp["preloadEnabled"]   = true;

                var rootVd          = rootApp.VirtualDirectories["/"];
                rootVd.PhysicalPath = physicalPath;

                var bindings = hostNames.SelectMany(
                    i => {
                    var nonsecureBinding = Tuple.Create(false, i.NonsecurePortSpecified ? i.NonsecurePort : 80, i.Name);
                    return(i.SecureBinding != null
                                                                                       ? new[] { nonsecureBinding, Tuple.Create(true, i.SecureBinding.PortSpecified ? i.SecureBinding.Port : 443, i.Name) }
                                                                                       : nonsecureBinding.ToCollection());
                })
                               .ToList();
                var unrecognizedBindings = new List <dynamic>();
                foreach (var iisBinding in site.Bindings)
                {
                    if (iisBinding.Protocol != "http" && iisBinding.Protocol != "https")
                    {
                        continue;
                    }

                    var bindingInfo = ((string)iisBinding.BindingInformation).Separate(":", false);
                    var binding     = Tuple.Create((string)iisBinding.Protocol == "https", int.Parse(bindingInfo[1]), bindingInfo[2]);
                    if (bindings.Contains(binding) && (!binding.Item1 || iisBinding.SslFlags == enumGetter("Microsoft.Web.Administration.SslFlags", "3")))
                    {
                        bindings.Remove(binding);
                    }
                    else
                    {
                        unrecognizedBindings.Add(iisBinding);
                    }
                }

                foreach (var i in unrecognizedBindings)
                {
                    site.Bindings.Remove(i);
                }

                foreach (var i in bindings)
                {
                    if (i.Item1)
                    {
                        site.Bindings.Add(
                            "*:{0}:{1}".FormatWith(i.Item2, i.Item3),
                            (byte[])null,
                            (string)null,
                            enumGetter("Microsoft.Web.Administration.SslFlags", "3"));
                    }
                    else
                    {
                        site.Bindings.Add("*:{0}:{1}".FormatWith(i.Item2, i.Item3), "http");
                    }
                }
            }));
        }
        /// <summary>
        /// Call this from Application_Start in your Global.asax.cs file. Besides this call, there should be no other code in the method.
        /// </summary>
        /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param>
        /// <param name="appInitializer">The application initializer, which performs web-site specific initialization and cleanup. If you have one of these you
        /// should name the class AppInitializer.</param>
        public static void InitStatics(SystemInitializer globalInitializer, SystemInitializer appInitializer = null)
        {
            // This is a hack to support data-access state in WCF services.
            var wcfDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            // Initialize system.
            var initTimeDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            try {
                GlobalInitializationOps.InitStatics(
                    globalInitializer,
                    Path.GetFileName(Path.GetDirectoryName(HttpRuntime.AppDomainAppPath)),
                    false,
                    mainDataAccessStateGetter: () => {
                    return(EwfApp.Instance != null ? EwfApp.Instance.RequestState != null ? EwfApp.Instance.RequestState.DataAccessState :
                           initTimeDataAccessState.Value :
                           System.ServiceModel.OperationContext.Current != null ? wcfDataAccessState.Value : null);
                });
            }
            catch {
                // Suppress all exceptions since there is no way to report them.
                return;
            }
            ewlInitialized = true;

            // Initialize web application.
            if (!GlobalInitializationOps.SecondaryInitFailed)
            {
                EwfApp.ExecuteWithBasicExceptionHandling(
                    () => {
                    EwfConfigurationStatics.Init();

                    GlobalConfiguration.Configure(WebApiStatics.ConfigureWebApi);

                    // Prevent MiniProfiler JSON exceptions caused by pages with hundreds of database queries.
                    MiniProfiler.Settings.MaxJsonResponseSize = int.MaxValue;

                    var globalType = BuildManager.GetGlobalAsaxType().BaseType;
                    if (!(globalType.Assembly.CreateInstance("EnterpriseWebLibrary.EnterpriseWebFramework." + globalType.Namespace + ".MetaLogicFactory") is
                          AppMetaLogicFactory metaLogicFactory))
                    {
                        throw new ApplicationException("Meta logic factory not found.");
                    }
                    EwfApp.Init(globalType, metaLogicFactory);

                    EwfPage.Init(
                        ModalBox.CreateBrowsingModalBox,
                        () => {
                        var cssInfos = new List <ResourceInfo>();
                        cssInfos.AddRange(EwfApp.MetaLogicFactory.CreateBasicCssInfos());
                        if (EwfUiStatics.AppMasterPage != null)
                        {
                            cssInfos.AddRange(EwfApp.MetaLogicFactory.CreateEwfUiCssInfos());
                        }
                        cssInfos.AddRange(EwfApp.Instance.GetStyleSheets());
                        if (EwfUiStatics.AppMasterPage != null)
                        {
                            cssInfos.AddRange(EwfUiStatics.AppProvider.GetStyleSheets());
                        }
                        return(cssInfos);
                    });
                    CssPreprocessingStatics.Init(globalInitializer.GetType().Assembly, globalType.Assembly);
                    HyperlinkBehaviorExtensionCreators.Init(ModalBox.GetBrowsingModalBoxOpenStatements);
                    EwfUiStatics.Init(globalType);

                    EwfInitializationOps.appInitializer = appInitializer;
                    appInitializer?.InitStatics();

                    initTimeDataAccessState     = null;
                    EwfApp.FrameworkInitialized = true;
                },
                    false,
                    false);
            }

            // If initialization failed, unload and restart the application after a reasonable delay.
            if (!EwfApp.FrameworkInitialized)
            {
                const int unloadDelay = 60000;                 // milliseconds
                initFailureUnloadTimer = new Timer(
                    state => EwfApp.ExecuteWithBasicExceptionHandling(
                        () => {
                    if (ConfigurationStatics.IsDevelopmentInstallation)
                    {
                        return;
                    }
                    HttpRuntime.UnloadAppDomain();

                    // Restart the application by making a request. Idea from Rick Strahl:
                    // http://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive.
                    //
                    // Disable server certificate validation so that this request gets through even for web sites that don't use a certificate that is trusted by
                    // default. There is no security risk since we're not sending any sensitive information and we're not using the response.
                    Tewl.Tools.NetTools.ExecuteWithResponse(
                        IisConfigurationStatics.GetFirstBaseUrlForCurrentSite(false),
                        response => {},
                        disableCertificateValidation: true);
                },
                        false,
                        false),
                    null,
                    unloadDelay,
                    Timeout.Infinite);
            }
        }
示例#12
0
        /// <summary>
        /// Call this from Application_Start in your Global.asax.cs file. Besides this call, there should be no other code in the method.
        /// </summary>
        // We could save people the effort of calling this by using trick #1 in
        // http://www.paraesthesia.com/archive/2011/02/08/dynamic-httpmodule-registration-in-asp-net-4-0.aspx, but that would probably require making this a static
        // method and would probably also cause this method to run at start up time in *all* web applications that reference the Standard Library, even the ones
        // that don't want to use EWF.
        protected void ewfApplicationStart(SystemLogic systemLogic)
        {
            // This is a hack to support data-access state in WCF services.
            var wcfDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            // Initialize system.
            var initTimeDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState());

            try {
                AppTools.Init(
                    Path.GetFileName(Path.GetDirectoryName(HttpRuntime.AppDomainAppPath)),
                    false,
                    systemLogic,
                    mainDataAccessStateGetter: () => {
                    // We must use the Instance property here to prevent this logic from always returning the request state of the *first* EwfApp instance.
                    return(Instance != null
                                                               ? Instance.RequestState != null ? Instance.RequestState.DataAccessState : initTimeDataAccessState.Value
                                                               : System.ServiceModel.OperationContext.Current != null ? wcfDataAccessState.Value : null);
                });
            }
            catch {
                // Suppress all exceptions since there is no way to report them.
                return;
            }
            ewlInitialized = true;

            // Initialize web application.
            if (!AppTools.SecondaryInitFailed)
            {
                executeWithBasicExceptionHandling(
                    () => {
                    EwfConfigurationStatics.Init();

                    // Prevent MiniProfiler JSON exceptions caused by pages with hundreds of database queries.
                    MiniProfiler.Settings.MaxJsonResponseSize = int.MaxValue;

                    GlobalType       = GetType().BaseType;
                    MetaLogicFactory =
                        GlobalType.Assembly.CreateInstance("RedStapler.StandardLibrary.EnterpriseWebFramework." + GlobalType.Namespace + ".MetaLogicFactory") as
                        AppMetaLogicFactory;
                    if (MetaLogicFactory == null)
                    {
                        throw new ApplicationException("Meta logic factory not found.");
                    }

                    // This initialization could be performed using reflection. There is no need for EwfApp to have a dependency on these classes.
                    if (systemLogic != null)
                    {
                        CssPreprocessingStatics.Init(systemLogic.GetType().Assembly, GlobalType.Assembly);
                    }
                    else
                    {
                        CssPreprocessingStatics.Init(GlobalType.Assembly);
                    }
                    EwfUiStatics.Init(GlobalType);

                    initializeWebApp();

                    initTimeDataAccessState = null;
                    initialized             = true;
                },
                    false,
                    false);
            }

            // If initialization failed, unload and restart the application after a reasonable delay.
            if (!initialized)
            {
                const int unloadDelay = 60000;                 // milliseconds
                initFailureUnloadTimer = new Timer(
                    state => executeWithBasicExceptionHandling(
                        () => {
                    if (AppTools.IsDevelopmentInstallation)
                    {
                        return;
                    }
                    HttpRuntime.UnloadAppDomain();

                    // Restart the application by making a request. Idea from Rick Strahl:
                    // http://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive.
                    //
                    // Disable server certificate validation so that this request gets through even for web sites that don't use a certificate that is trusted by
                    // default. There is no security risk since we're not sending any sensitive information and we're not using the response.
                    NetTools.ExecuteWithResponse(IisConfigurationStatics.GetFirstBaseUrlForCurrentSite(false), response => { }, disableCertificateValidation: true);
                },
                        false,
                        false),
                    null,
                    unloadDelay,
                    Timeout.Infinite);
            }
        }