I have a library that needs to respond to exceptions in different ways depending on whether it is running in a Console app, WinForms, AspNet or Windows Service. I have experimented with looking at various properties in the System.Windows.Forms and System.Web namespaces, but I can't find a reliable way of detecting exactly which kind of application is hosting my library. Has anyone been here before? Does anyone have a reliable solution?
This feels like you would want to look into the design a bit more, is my spontaneous though. A class library should not need to know things like that about its caller.
What is it that you want to change in the exception handling behaviour based on the context in which it is running?
Based on your comment, I would suggest looking into defining an interface for an error handler, and then create the needed number of implementations of that interface (one for WinForms, one for Console and so on), and have the client application create and inject the corresponting implementation into the library. That way you lift the knowledge-need out from the library and shift the responsibility over to the client application. These implementations can still reside inside your class library, but the decision of which to use will be for the client application to make.
If I understand what you are seeking correctly, you have a single library that does error handling, but you want the library to know if the source is web, console, winforms, etc.?
You might be able to utilize a property in the library, say an enumeration, that tracks what the consuming applications type is. For example...
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.WinForm);
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Web);
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Console);
EDIT
From Samir in comments...
In addition you could always just have a class for each type of application implement the same interface within your error logger library.
For example in a Web Application you would utilize:
WebErrorLogger error = new WebErrorLogger();
This sounds like something that would be best handled with configuration. Perhaps injection of something like an IExceptionHandler interface via an IOC.
I'd question your design before going down this route but I thought this was an interesting challenge and wanted to see if I could find anyways.
ASP.Net : Check HttpContext.Current is not null. You could also look at System.Web.Hosting.ApplicationManager.GetApplicationManager(), but I'm not sure how this will behave outside of Asp.net
Window Forms: You could try and use System.Windows.Forms.Application.OpenForms, this will return any open forms. An assumption is being made that a windows form application would never not have any forms. Also a console application can also start a win form.
Service: Not sure on this but I'm wondering if you can check the name of the process. There must also be a windows API since the task manager shows when a process is a service (At least on Vista it does)
BOOL IsConsole(PBYTE file)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)file;
if(pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS pImageHeaders = (PIMAGE_NT_HEADERS)(file + pDosHeader->e_lfanew);
if(pImageHeaders->Signature == IMAGE_NT_SIGNATURE)
{
IMAGE_OPTIONAL_HEADER optionalHeader = pImageHeaders->OptionalHeader;
return (optionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
}
}
return FALSE;
}
IMAGE_SUBSYSTEM_WINDOWS_CUI
can be excahnged with IMAGE_SUBSYSTEM_WINDOWS_GUI
to detect whether it's a GUI application instead of console.
Services in windows usually have 'services.exe
' as their parent, the way of determining the parent process is well described over at CodeProject.
ASP.NET process runs under special user called ASPNET, user's name can be obtained from an access token .