JetBrains Rider: How to stop and start an IIS app pool on solution build
Tags: aspdotnet, webdev
Published: 2023-08-23 16:48:16

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**

```powershell
$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"
}
```

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**

```powershell
$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"
}
```

**Configure the pre and post build events**

Pre build:

```powershell
powershell -ExecutionPolicy Bypass -File "StopApplicationPool.ps1"`
```
Post build:
```powershell
powershell -ExecutionPolicy Bypass -File "StartApplicationPool.ps1"`
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyspobbqt0za11j32szy.png)

That's it. Happy building 😀