Home > Mobile >  What does Visual Studio do to start IIS when debugging?
What does Visual Studio do to start IIS when debugging?

Time:09-03

We are developing an (internal) web service based on asp.net 4.8, with a fairly extensive REACT SPA front end.

For debugging purposes during development, we run an IIS server on the local (development) machine, and we do something separate to run a proxy web server for debugging the .js front end SPA (not relevant to the question at hand).

When we start up a Debug session in Visual Studio (2019), VS starts with "Contacting web server to start debugging" and then locks for a time. It clearly does something to start the web server (w3wp.exe), and waits for some reply, before doing what it is told to do in the "Start Action" section of the Web tab on the project properties page.

This is problematic behaviour because it does not attach to w3wp.exe until after it finishes it's "contacting web server to start debugging" operation. This is a huge problem, as our w3wp.exe starts doing all kinds of things that we have no visibility into.

So, can anyone explain to me:

  1. What does VS actually do to "contact the web server"?
  2. Can this be controlled? If so, how?
  3. Can I get the debugger to attach to w3wp.exe right away?
  4. Why does w3wp.exe start up and load its collection of binaries, only unload them and reload them, sometime multiple times?

In short, what the actual heck is going on under the covers at startup?

This (Identity Server 3 Contacting the web server hangs when launching debug mode) question and answer seem irrelevant to my situation

I note the field Override application root URL in the Servers section of the Web tab of the project properties and had hoped this might have something to do with it, but I cannot see any relation.

CodePudding user response:

Partial answers that I will either edit as I find more info, or modify if others correct me, or delete if someone answers completely. The answers to (1) and (2) above are this:

  1. VS obtains the URL of the target web site (I will call this targetServer) from the Project URL entry in the Servers section, Web tab, of the Properties page for the web project. This actually comes from the <webProjectName>.csproj.user file in the project directory. Depending on the selection of the drop down specifying the server type to use, it comes from:
    • IIS server (<UseIIS>true): the <IISUrl> element
    • External Host (<UseCustomServer>true): the <CustomServerUrl>
    • IIS Express: unknown
  2. WARNING: When opening a project with <UseIIS>true, Visual Studio has the very nasty habit of interfering in the setup of your IIS server: it insists on changing the "Physical Location" attribute of the IIS server (that is, the server or virtual app, however you have it set up) to point to the project directory of the web project. Using the "External Host" option avoids this - see https://stackoverflow.com/a/48753054/1082063. (All other discussions of this issue that I have seen incorrectly say this cannot be controlled.)
  3. VS then issues a request to the url <targetServer>/debugAttach.aspx, and the request shows as neither a "GET" nor a "POST", but a "DEBUG", whatever that is. Not sure what VS expects back from this before doing the specified Start Action
  4. Presumably after VS gets some reply from its DEBUG request, it will attach to the process that resulted from this request. Not sure how it knows which process to attach to - perhaps the debugAttach.aspx returns process information?
  5. VS finally executes whatever Start Action is specified in the section of that name on the Web tab of the project Properties.

I strongly suspect that the answer to (3) above is that one cannot get VisualStudio to attach any earlier than it does because it must use the information returned from the debugAttach.aspx request to know which process to attach to. However, putting the line System.Diagnostics.Debugger.Launch(); at the start of Application_Start will allow you to attach the debugger earlier when necessary. (In practice, once you get Application_Start correct, you seldom need to debug it.) See this: https://weblog.west-wind.com/posts/2011/Dec/15/Debugging-ApplicationStart-and-Module-Initialization-with-IIS-and-Visual-Studio for a very good article on the subject.

(4) was a result of quirks in our Visual Studio setup. The initial "hack" used to get around the WARNING in answer (2) just above, was to have a web site with a dummy "virtual path" and have the IISUrl element in Visual Studio point to this virtual path. Then VS could change the Physical path of this virtual path, and we didn't really care, because our Start Action was to start a proxy server for debugging .js in any case. The issue was that this resulted in two calls to Application_start, running on two separate threads: one for the main server and one for the virtual server. Because one of these was happening before the attach happened, we never knew it was happening and it was never caught in a break point. When our application_start became long (timewise - this is not a web server for public consumption...), the two executions of application_start became a nightmare.

CodePudding user response:

The issue you're seeing in IIS is that VS is not launching w3wp.exe, but rather Attaching to Process. In order for VS to attach though the EXE has to be running first, and the time between starting up and attaching (if not already running) ends up being too late to catch the ASP.NET app initialization logic in Application_Start and Module initialization.

As mentioned in my old post there are several ways you can get this to work:

  • Restarting the application when the debugger is already attached
    (by making a change in web.config to trigger an AppDomain reload)
  • Adding an explicit Debugger.Break() call in Application_Start
  • Use IIS Express to debug startup code
  • Related