DEV Community

Cover image for JetBrains Rider: How to stop and start an IIS app pool on solution build
Michael Eustace
Michael Eustace

Posted on • Updated on

JetBrains Rider: How to stop and start an IIS app pool on solution build

I recently made the switch from Visual Studio to JetBrains Rider for my .NET Core web application projects.

Whilst I am very pleased with the new development experience, there was one issue that I had to overcome.

The problem

When building a solution where I was running the web application in a locally hosted IIS instance, the build often failed because of the error below:

Microsoft.Common.CurrentVersion.targets(4685, 5): [MSB3027] Could not copy "obj\Debug\net7.0\foo.dll" to "bin\Debug\net7.0\foo.dll". Exceeded retry count of 10. Failed. The file is locked by: "IIS Worker Process (10592)

This was because the IIS Worker Process had locked the DLL files in the bin directory, causing the build to fail when it attempted to overwrite them.

The solution

The solution is to stop the application pool for the website in IIS to release the lock, perform the build, then start the app pool again.

If you had configured Visual Studio to run using the local IIS website, then it would take care of stopping and starting the app pool for you, but JetBrains Rider doesn't do this.

The work around is to create two powershell scripts to stop and start the app pool, then configure pre and post build events when your web project build is triggered.

Here is the code for the two PowerShell scripts. Copy and paste the code into two files and store them in the root of the web project in Rider.

StopApplicationPool.ps1

$AppPoolName = "<app_pool_name>"

if ($AppPoolStatus -eq "Started") {
    Write-Host "Stopping application pool $AppPoolName..."
    Stop-WebAppPool -Name $AppPoolName

    # Wait loop to check the status of the application pool
    do {
        Write-Host "Waiting for application pool to stop..."
        Start-Sleep -Seconds 1  # Wait for 1 seconds before checking again
        $AppPoolStatus = (Get-WebAppPoolState -Name $AppPoolName).Value
    } while (($AppPoolStatus -eq "Started") -or ($AppPoolStatus -eq "Stopping"))

    Write-Host "Application pool $AppPoolName has been stopped."
} 
elseif ($AppPoolStatus -eq "Stopping") {
    # Wait loop to check the status of the application pool
    do {
        Write-Host "Waiting for application pool to stop..."
        Start-Sleep -Seconds 1  # Wait for 1 seconds before checking again
        $AppPoolStatus = (Get-WebAppPoolState -Name $AppPoolName).Value
    } while ($AppPoolStatus -eq "Stopping")

    Write-Host "Application pool $AppPoolName has been stopped."
}
elseif ($AppPoolStatus -eq "Stopped") {
    Write-Host "Application pool $AppPoolName is already stopped."
} else {
    Write-Host "Application pool $AppPoolName is in an unknown state: $AppPoolStatus"
}
Enter fullscreen mode Exit fullscreen mode

Notice the script above polls the app pool status until it's actually reporting the status as Stopped, before exiting to allow the build to begin. Remember, application pools don't stop immediately, they shutdown gracefully to allow any processes that were in-progress, at the point when the stop command was issued, to complete.

StartApplicationPool.ps1

$AppPoolName = "<app_pool_name>"

$AppPoolStatus = (Get-WebAppPoolState -Name $AppPoolName).Value

if ($AppPoolStatus -eq "Stopped") {
    Write-Host "Starting application pool $AppPoolName..."
    Start-WebAppPool -Name $AppPoolName
    Write-Host "Application pool $AppPoolName has been started."
} elseif ($AppPoolStatus -eq "Started") {
    Write-Host "Application pool $AppPoolName is already started."
} else {
    Write-Host "Application pool $AppPoolName is in an unknown state: $AppPoolStatus"
}
Enter fullscreen mode Exit fullscreen mode

Configure the pre and post build events

Pre build:

powershell -ExecutionPolicy Bypass -File "StopApplicationPool.ps1"`
Enter fullscreen mode Exit fullscreen mode

Post build:

powershell -ExecutionPolicy Bypass -File "StartApplicationPool.ps1"`
Enter fullscreen mode Exit fullscreen mode

In Rider, open the Properties for the project and copy and paste the above into the fields highlighted below.

Executing commands before and after build events in JetBrains Rider

That's it. Happy building 😀

Top comments (0)