Tuesday, September 16, 2014

Enable autostart in IIS 7.5 (without AppFabric)

You can create your own autostart provider for your WCF services and there is no need to use AppFabric for autostarting WCF services.

You will need/configure 4 things to enable autostart in WCF
            1) Autostartprovider (source code below)
            2) Add the reference of the above library to your WCF service
            3) Modify the svc file to use factory - 

<%@ ServiceHost Language="C#" Debug="true" Service="Service1" CodeBehind="Service1.svc.cs" Factory="Web.Hosting.ServiceBusHostFactory" %>

            4) Modify the applicationHost.config in C:\Windows\System32\Inetsrv\config in the following places

a) At AppPool level
                       <add name="AutoStartSite" managedRuntimeVersion="v4.0" autoStart="true" startMode="AlwaysRunning"  />



b) At Site level -
                      <site name="AutoStartSite" id="2" serverAutoStart="true">


c) At Virtual directory/Application level
                      <application path="/AutoStartVD" applicationPool="AutoStartSite" serviceAutoStartEnabled="true" serviceAutoStartProvider="MyAutoStartProvider">


d) serviceAutoStartProviders itself -
                       
In your applicationHost config file between <webLimits/> and    </system.applicationHost>, add the following section - 

         <serviceAutoStartProviders>
            <add name="MyAutoStartProvider" type="Web.Hosting.AutoStartProvider, Web.Hosting" />
        </serviceAutoStartProviders>



Thats it. Deploy your WCF service. Fire up DbgView.exe for debugging purposes as there are some diagnostics statements in the AutoStartProvider.




================START Autostartprovider source code=======================

File::::AutoStartProvider.cs

using System;
using System.Diagnostics;
using System.IO;
using System.ServiceModel;
using System.Threading;
using System.Web.Hosting;


namespace Web.Hosting
{
    public class AutoStartProvider : IProcessHostPreloadClient
    {
        
        public void Preload(string[] parameters)
        {
            bool isServceActivated = false;
            int attempts = 0;
            while (!isServceActivated && (attempts < 10))
            {
                Thread.Sleep(1 * 1000);
                try
                {
                    if (!System.Web.Hosting.HostingEnvironment.IsHosted) 
                        return;

                    var virtualPath = HostingEnvironment.ApplicationVirtualPath;
                    var physicalPath = HostingEnvironment.ApplicationPhysicalPath;
                    var svcFiles = Directory.GetFiles(physicalPath, "*.svc");

                    foreach (string svcFile in svcFiles)
                    {
                        ServiceHostingEnvironment.EnsureServiceAvailable(virtualPath + "/" + Path.GetFileName(svcFile));
                    }

                    isServceActivated = true;
                    System.Diagnostics.Trace.WriteLine(String.Format("Activated {0}", virtualPath));
                }
                catch (Exception exception)
                {
                    attempts++;
                    //continue on these exceptions, otherwise fail fast
                    if (exception is EndpointNotFoundException
                        || exception is ServiceActivationException
                        || exception is ArgumentException)
                    {
                        System.Diagnostics.Trace.WriteLine(exception.Message);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
    }

}

-------------------------------------------------------------------------------------------------------------

File::::ServiceBusHostFactory.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Text;
using System.Threading.Tasks;

namespace Web.Hosting
{
    public class ServiceBusHostFactory : ServiceHostFactory
    {
    Type incomingServiceType;
    Uri[] incomingBaseAddresses;
    /// <summary>
    /// Reopen Service host on network intermittent error
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnServiceHostFaulted(object sender, EventArgs e)
    {
        ICommunicationObject faultedHost = (ICommunicationObject) sender;
        faultedHost.Abort();
        //Log failure
        bool IsSourceExist = EventLog.SourceExists(CustomEventLogInstaller.EventSourceName);
        if (IsSourceExist)
            EventLog.WriteEntry(CustomEventLogInstaller.EventSourceName,
                String.Format("Host {0} connection failed at address {1}",this.incomingServiceType.ToString(),
                        this.incomingBaseAddresses.FirstOrDefault()), EventLogEntryType.Error);
        ServiceHost host =  base.CreateServiceHost(this.incomingServiceType, this.incomingBaseAddresses);       
        host.Faulted += this.OnServiceHostFaulted;
        System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10)); // Sleeping here just to allow some time for the resource to come back.
        host.Open();
        //log host reopened
        if (IsSourceExist)
            EventLog.WriteEntry(CustomEventLogInstaller.EventSourceName,
                String.Format("Service bus connection reopened for {0}", this.incomingBaseAddresses.FirstOrDefault()), EventLogEntryType.Information);
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
    this.incomingServiceType = serviceType;
    this.incomingBaseAddresses = baseAddresses;
    ServiceHost host = base.CreateServiceHost(this.incomingServiceType, this.incomingBaseAddresses);
    host.Faulted += this.OnServiceHostFaulted;
    return host;
    }
 }

}

================END Autostartprovider source code=======================

Uninstalling and reinstalling IIS 7.5 on Windows 7

If you want remove IIS 7.5 from your Windows 7 machine, make sure to remove IIS Hostable Web Core and Windows Process Activation Service (if already installed).

Uninstalling just IIS features and reinstalling them will not help and you will get - "An error occurred. Not all features are installed".

Here are steps-
1) Uninstall IIS, IIS HWC, WAS.
2) Restart the system
3) Rename Inetpub to Inetpub1
4) Reinstall IIS