3

I have a .NET 6 IHostedService hosted on IIS 10 Windows Server 2019.

I am aiming for

  • startup the application after server reboot
  • startup the application after iisreset
  • startup the application after iisreset /start

I followed the SO post here and this blog post

Regarding SO post's answer:

  • I did a reboot of server
  • followed all steps

Regarding the blog post:

  • I tried setting the CLR to both "No Managed Code" and "v4.0"

I have found some mention on other sites that I have to have anonymous auth enabled - this was also tested (see below in applicationhost.config)

However I can't have this basic feature of IIS up and running. According to SO post and blog post, it seems that it helped most of the people.

web.config:

<?xml version="1.0" encoding="utf-8"?>
   <configuration>
       <location path="." inheritInChildApplications="false">
           <system.webServer>
               <handlers>
                   <remove name="aspNetCore" />
                   <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
               </handlers>
               <aspNetCore processPath="dotnet" arguments=".\<obfuscated>.dll" 
                           stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" 
                           hostingModel="inprocess">
                   <environmentVariables>
                       <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
                   </environmentVariables>
               </aspNetCore>
            </system.webServer>
        </location>
    </configuration>

applicationhost.config:

<?xml version="1.0" encoding="UTF-8"?>
< ... />
<configuration>
    <system.applicationHost>
        <applicationPools>
            <add name="obfuscated" autoStart="true" managedRuntimeVersion="v4.0" startMode="AlwaysRunning">
                <processModel identityType="SpecificUser" userName="obfuscated" password="obfuscated" idleTimeout="00:00:00" />
            </add>
            <applicationPoolDefaults managedRuntimeVersion="v4.0">
                <processModel identityType="ApplicationPoolIdentity" />
                <recycling logEventOnRecycle="Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory">
                    <periodicRestart time="00:00:00" />
                </recycling>
            </applicationPoolDefaults>
        </applicationPools>

        < ... />
      
        <sites>
            <site name="obfuscated" id="1">
                <application path="/" applicationPool="obfuscated" preloadEnabled="true">
                    <virtualDirectory path="/" physicalPath="obfuscated" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="obfuscated" />
                </bindings>
            </site>
            <siteDefaults>
                <logFile logExtFileFlags="Date, Time, ClientIP, UserName, SiteName, ComputerName, ServerIP, Method, UriStem, UriQuery, HttpStatus, Win32Status, TimeTaken, ServerPort, UserAgent, Referer, Host, HttpSubStatus" logFormat="W3C" directory="obfuscated">
                </logFile>
                <traceFailedRequestsLogging directory="obfuscated" />
            </siteDefaults>
            <applicationDefaults applicationPool="DefaultAppPool" />
            <virtualDirectoryDefaults allowSubDirConfig="true" />
        </sites>

        <webLimits />
    </system.applicationHost>

    <system.webServer>

        <asp />

        <caching enabled="true" enableKernelCache="true">
        </caching>

        <cgi />

        <defaultDocument enabled="true">
            <files>
                <add value="Default.htm" />
                <add value="Default.asp" />
                <add value="index.htm" />
                <add value="index.html" />
                <add value="iisstart.htm" />
                <add value="default.aspx" />
            </files>
        </defaultDocument>

        <directoryBrowse enabled="false" />

        <fastCgi />
        <!--
          The <globalModules> section defines all native-code modules.
          To enable a module, specify it in the <modules> section.
        -->
        <globalModules>
            <add name="HttpLoggingModule" image="%windir%\System32\inetsrv\loghttp.dll" />
            <add name="UriCacheModule" image="%windir%\System32\inetsrv\cachuri.dll" />
            <add name="FileCacheModule" image="%windir%\System32\inetsrv\cachfile.dll" />
            <add name="TokenCacheModule" image="%windir%\System32\inetsrv\cachtokn.dll" />
            <add name="HttpCacheModule" image="%windir%\System32\inetsrv\cachhttp.dll" />
            <add name="DynamicCompressionModule" image="%windir%\System32\inetsrv\compdyn.dll" />
            <add name="StaticCompressionModule" image="%windir%\System32\inetsrv\compstat.dll" />
            <add name="DefaultDocumentModule" image="%windir%\System32\inetsrv\defdoc.dll" />
            <add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
            <add name="ProtocolSupportModule" image="%windir%\System32\inetsrv\protsup.dll" />
            <add name="HttpRedirectionModule" image="%windir%\System32\inetsrv\redirect.dll" />
            <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
            <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
            <add name="UrlAuthorizationModule" image="%windir%\System32\inetsrv\urlauthz.dll" />
            <add name="WindowsAuthenticationModule" image="%windir%\System32\inetsrv\authsspi.dll" />
            <add name="IpRestrictionModule" image="%windir%\System32\inetsrv\iprestr.dll" />
            <add name="DynamicIpRestrictionModule" image="%windir%\System32\inetsrv\diprestr.dll" />
            <add name="RequestFilteringModule" image="%windir%\System32\inetsrv\modrqflt.dll" />
            <add name="CustomErrorModule" image="%windir%\System32\inetsrv\custerr.dll" />
            <add name="RequestMonitorModule" image="%windir%\System32\inetsrv\iisreqs.dll" />
            <add name="IsapiModule" image="%windir%\System32\inetsrv\isapi.dll" />
            <add name="IsapiFilterModule" image="%windir%\System32\inetsrv\filter.dll" />
            <add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
            <add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
            <add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
            <add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
            <add name="ConfigurationValidationModule" image="%windir%\System32\inetsrv\validcfg.dll" />
            <add name="WebSocketModule" image="%windir%\System32\inetsrv\iiswsock.dll" />
            <add name="RewriteModule" image="%SystemRoot%\system32\inetsrv\rewrite.dll" />
            <add name="AspNetCoreModuleV2" image="%ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll" />
        </globalModules>

        < ... />

        <security>

            <access sslFlags="None" />

            <applicationDependencies />

            <authentication>

                <anonymousAuthentication enabled="true" userName="IUSR" />

                <basicAuthentication />

                <clientCertificateMappingAuthentication />

                <digestAuthentication />

                <iisClientCertificateMappingAuthentication />

                <windowsAuthentication enabled="false" authPersistNonNTLM="true">
                    <providers>
                        <add value="Negotiate" />
                        <add value="NTLM" />
                    </providers>
                </windowsAuthentication>

            </authentication>

            <authorization>
                <add accessType="Allow" users="*" />
            </authorization>

            <ipSecurity allowUnlisted="true" />

            <isapiCgiRestriction>
                <add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
                <add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
                <add path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v4.0.30319" description="ASP.NET v4.0.30319" />
                <add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v4.0.30319" description="ASP.NET v4.0.30319" />
            </isapiCgiRestriction>

            < ... />

        </security>

        < ... />

    </system.webServer>
    <location path="" overrideMode="Allow">
        <system.webServer>

        <modules>
          < ... />
        </modules>

        <handlers accessPolicy="Read, Script">
              < ... />
        </handlers>
        </system.webServer>
    </location>

</configuration>
pandemic
  • 1,135
  • 1
  • 22
  • 39
  • What I can be sure of is that you have everything set up for the app to start automatically. But how can you be sure that the app isn't launching? Maybe it's already started and you just didn't notice it. Please check Worker processes module of IIS or w3wp.exe in task manager. Stop application and confirm worker process stop. Then start application without send any requests. Check if process is there. – Bruce Zhang Feb 10 '22 at 07:03
  • as the app is spamming lots of logs on the startup and in next seconds as well. I am pretty sure. it stays "iddle" forever until I send a wake up call to the controller. right after that the app kicks in and vomits logs – pandemic Feb 10 '22 at 09:06

1 Answers1

0

You should enable Application Initialization module on the server to restart the application automatically.

By default in IIS, if no request is sent to the application for 20 minutes, the application will be suspended.

enter image description here

This PowerShell script can help you to keep your application always live

## IIS WebAdmin Module
    Import-Module WebAdministration

    $AppPoolInstance = Get-Item IIS:\AppPools\$AppPool

    Write-Output "Set Site PreLoadEnabled to true"
    Set-ItemProperty IIS:\Sites\$Site -name applicationDefaults.preloadEnabled -value True

    Write-Output "Set Recycling.periodicRestart.time  = 0"
    $AppPoolInstance.Recycling.periodicRestart.time = [TimeSpan]::Parse("0");
    $AppPoolInstance | Set-Item

    Write-Output "Set App Pool start up mode to AlwaysRunning"
    $AppPoolInstance.startMode = "alwaysrunning"

    Write-Output "Disable App Pool Idle Timeout"
    $AppPoolInstance.processModel.idleTimeout = [TimeSpan]::FromMinutes(0)
    $AppPoolInstance | Set-Item

    if ($appPoolStatus -ne "Started") {
        Write-Output "Starting App Pool"
        Start-WebAppPool $AppPool
    } else {
        Write-Output "Restarting App Pool"
        Restart-WebAppPool $AppPool
    }

Note: you should change the $AppPool and $Site names to your application


This link maybe helpful for you

Farhad Zamani
  • 5,381
  • 2
  • 16
  • 41
  • applicationInitialization module was installed as well which I mentioned by stating "followed all steps" of the SO post which mentions that – pandemic Feb 11 '22 at 12:12