From a class library, I need to determine at run-time whether I'm running in an ASP.NET app or a WinForms/console app. There have been several other questions asked on the subject, but all of those solutions require adding a reference to System.Web. If at all possible, when running my console and WinForms apps, I don't want to load the System.Web assembly into memory just for one line of code out of thousands.
8 Answers
Use System.Diagnostics.Process.GetCurrentProcess().ProcessName
If you're running ASP.NET then the assembly will be named thusly:
If you are running IIS 6.0 or IIS 7.0, the name is w3wp.exe.
If you are running an earlier version of IIS, the name is aspnet_wp.exe.
Another Idea: How about testing the process/app domain for the presence of the System.Web.dll with the AppDomain.CurrentDomain.GetAssemblies() API?

- 79,492
- 20
- 149
- 189
-
1GetExecutingAssembly() returns the assembly containing the currently-executing line of code. For a class library located in a DLL referenced by applications of various types, that will always be the same regardless of which app is referencing it. – KeithS Mar 28 '11 at 21:11
-
I like this because it's simple, and I'm already getting the value of `System.Diagnostics.Process.GetCurrentProcess().ProcessName` as a starting point. However, checking for specific return values feels kind of hacky. If the name of the process changes with IIS 8, I'd have to update my app. I'll have to give it some thought. – Billy Jo Mar 29 '11 at 01:24
-
Yes, it is a hack. I actually first came across it when trying to determine whether or not the custom control I was creating was in design mode or runtime. For that I had to check to see if the owner process was an IDE or not. The Control.DesignMode property did not actually work. That said, it is a good idea to hedge your bets. Have you checked into any other alternatives such as detectic whether or not some core ASP.NET DLLs are loaded in the same process? That ought to be a solid clue. – Paul Sasik Mar 29 '11 at 02:52
-
@Bill: Check my "Another Idea" edit above. It might work for you. Though a caveat could be that the assembly might be loaded if the app you're running in uses web APIs... – Paul Sasik Mar 29 '11 at 03:05
-
1I haven't tested this and it may be overkill but could you load the System.Web assembly via Reflection into a separate appdomain and then destroy it once you're done? This would at least not really be a hack and works around loading the assembly as part of the application for its entire duration. – kamranicus Mar 29 '11 at 03:59
-
@subkamran: App domains actually make it easy to load and unload assemblies. Many .NET IoC frameworks make great use of this feature. See Castle Windsor, for eaxmple: http://docs.castleproject.org/Windsor.MainPage.ashx But, i'm not sure if doing so would accomplish much. You would be able to load the systemweb.dll into any .NET app regardless of whether it's ASP.NET, console or WinForm. – Paul Sasik Mar 29 '11 at 04:32
-
I'm accepting this answer because 1) it's simple to implement; 2) I'm already getting I'm already getting `System.Diagnostics.Process.GetCurrentProcess().ProcessName` for non-web apps; and 3) IIS's process name is a meaningful default if it changes with IIS 8 or if I fail to determine the name another way. Thanks for your help, Paul. – Billy Jo Apr 13 '11 at 17:40
One of the questions you linked to contained an answer suggesting Environment.UserInteractive.
You could also try to analyze the StackTrace of your code to figure out where you are called from.
-
2`Environment.UserInteractive` returns `false` when a console app is running from the Windows Task Scheduler, so I can't rely on it as a flag that differentiates web apps from console apps. I'll try analyzing a stack trace and see what I can come up with. – Billy Jo Mar 29 '11 at 01:18
-
2
You could try something based on Assembly.GetEntryAssembly(). As noted in the comment below, GetEntryAssembly() returns NULL if the current code is being run in the context of a web application or service. It will return some non-null reference in cases of standalone apps such as WinForm or console apps.
Edited to change the original answer because of the comment.

- 70,210
- 21
- 112
- 164
-
1`Assembly.GetEntryAssembly()` returns `null` for web apps and web services. Good thought, though. – Billy Jo Mar 29 '11 at 01:03
-
1Well then that's a possible solution; if GetEntryAssembly() returns null you're in a web environment, whereas if it comes back with something you're in some standalone environment. – KeithS Mar 29 '11 at 14:39
-
2There's no guarantee it's web. Docs: "[I]f an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly." – Billy Jo Mar 29 '11 at 15:24
-
1It returnes null also if it is called from MS Test as it is not an executable – EvAlex Nov 21 '12 at 06:09
Yet another hack:
System.Configuration.ConfigurationManager.OpenExeConfiguration throws an ArgumentException with a specific message if you're not running inside a standalone exe. You could use that fact to check in this manner:
bool notAnExe = false ;
try
{
// see if we're running in an exe.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
catch(ArgumentException aex)
{
if(aex.Message == "exePath must be specified when not running inside a stand alone exe.")
{
notAnExe = true ;
}
}

- 361
- 2
- 7
-
This is because the ConfigurationManager is expecting a call from ASP.NET to set a configuration system other that client. See .NET source code at https://referencesource.microsoft.com/#System.Configuration/System/Configuration/ConfigurationManager.cs,ce182a288ad7694d – David Burg Apr 01 '21 at 02:50
This is an old thread, but here is new answer that isn't a hack.
private bool IsExe()
{
var domainManager = AppDomain.CurrentDomain.DomainManager;
if (domainManager == null) return false;
var entryAssembly = domainManager.EntryAssembly;
if (entryAssembly == null) return false;
return entryAssembly.Location.EndsWith(".exe", StringComparison.OrdinalIgnoreCase);
}
This will not tell you if the application is ASP.Net or not, but it will tell you if this is a console or WinForms app which is the opposite approach to most of the other answers here. For example if this is an OWIN application the IsExe
method will return false even though this is not an ASP.Net application.

- 2,236
- 23
- 30
You can check System.Diagnostics.Process.GetCurrentProcess().ProcessName;. If it starts with aspnet, then it's asp.net. Otherwise, desktop.

- 12,088
- 10
- 40
- 50
It may appear like a hack. It uses the DomainManager type of Current AppDomain. Check also AppDomainManager
public static class AspContext
{
public static bool IsAspNet()
{
var appDomainManager = AppDomain.CurrentDomain.DomainManager;
return appDomainManager != null && appDomainManager.GetType().Name.Contains("AspNetAppDomainManager");
}
}
Or you can use this other answer on SO
HostingEnvironment.IsHosted

- 1,813
- 3
- 18
- 23
-
That requires System.Web, which I specifically stated in the question I did _not_ want to reference. – Billy Jo Nov 22 '17 at 19:12
-
Sorry didn't read the question in detail. ;-) But this solution worked OK for what I needed and I didn't see it anywhere out there. So I thought I'd throw it out there. – Tom Winter Nov 22 '17 at 19:24