Post

How Visual Studio Launches IIS Express to Debug ASP.NET Core Apps

Note that for a published ASP.NET Core web app, the magic described below is not applicable, as a web.config file would be generated by dotnet publish command, which contains the necessary settings.

I guess many of you are familiar with IIS Express and its command line. So we can easily launch it and host a web site locally. That works greatly for classic web sites (classic ASP, ASP.NET 4.x, and so on), including the web sites generated by dotnet publish command.

However, if you happen to use the same command line to launch IIS Express and try to host an ASP.NET Core project and its source code directly, you might suddenly realize that you cannot (HTTP Error 502.5 - Process Failure). Why?

img-description Figure 1: Process Failure 502.5 error page.

If we go to Windows event log to dig the details, the following sounds interesting,

1
2
3
4
5
6
7
8
9
10
11
Log Name: Application
Source: IIS Express AspNetCore Module
Date: 6/5/2017 8:11:19 PM
Event ID: 1000
Task Category: None
Level: Error
Keywords: Classic
User: N/A
Computer: lextmserver
Description:
Application 'MACHINE/WEBROOT/APPHOST/WEBAPPLICATION2' with physical root 'C:\Users\lextm\documents\visual studio 2017\Projects\WebApplication2\WebApplication2\' failed to start process with commandline '"%LAUNCHER_PATH%" %LAUNCHER_ARGS%', ErrorCode = '0x80070002 : 0.

So it seems that there are two environment variables missing. Should you ask Google, you will see tons of posts on them, and people suggest they be set in web.config file. OK, can you follow them? Unfortunately, you cannot this time, as this project (from official template) has no web.config file at all,

img-description Figure 2: ASP.NET Core project folder (no web.config file).

So what magic does Visual Studio use to launch the web app?

Hints only come if you ask Process Explorer,

img-description Figure 3: Process Explorer shows the special launcher.

img-description Figure 4: Process Explorer shows special environment variables.

So Visual Studio silently adds the two environment variables when launching IIS Express, so that ASP.NET Core related bits can be injected,

  • LAUNCHER_ARGS: -debug -p "C:\Program Files\dotnet\dotnet.exe" -a "exec \"C:\Users\lextm\documents\visual studio 2017\Projects\WebApplication2\WebApplication2\bin\Debug\netcoreapp1.0\WebApplication2.dll\"" -pidFile "C:\Users\lextm\AppData\Local\Temp\2\tmpFD6D.tmp" -wd "C:\Users\lextm\documents\visual studio 2017\Projects\WebApplication2\WebApplication2"
  • LAUNCHER_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\Extensions\Microsoft\Web Tools\ProjectSystem\VSIISExeLauncher.exe

Please notice a few interesting facts,

  • When IIS Express is launched without any access to the ASP.NET Core web app, VSIISExeLauncher.exe would not be called. This process only starts when a request comes.
  • When LAUNCHER_ARGS contains the -debug flag, dotnet.exe process would start and enter SUSPENDED state immediately. I guess this gives Visual Studio a chance to attach the debugger. If you intend to test the web app without debugging, you can remove this flag.

I found the above details while investigating a Jexus Manager issue, and hope it helps you better understand the magic Microsoft uses behind the scene.

Jexus Manager uses the following code to simulate Visual Studio behaviors, so as to host ASP.NET Core projects.

If you intend to automate IIS Express to host such projects, you might follow the logic.

© Lex Li. All rights reserved. The code included is licensed under CC BY 4.0 unless otherwise noted.