我有一个库需要根据运行环境的不同方式来响应异常,包括控制台应用程序、WinForms、AspNet或Windows服务。我已经尝试查看System.Windows.Forms和System.Web命名空间中的各种属性,但是我找不到一种可靠的方法来检测哪种类型的应用程序托管了我的库。有人遇到过这种情况吗?有没有可靠的解决方案?
我有一个库需要根据运行环境的不同方式来响应异常,包括控制台应用程序、WinForms、AspNet或Windows服务。我已经尝试查看System.Windows.Forms和System.Web命名空间中的各种属性,但是我找不到一种可靠的方法来检测哪种类型的应用程序托管了我的库。有人遇到过这种情况吗?有没有可靠的解决方案?
如果我正确理解你的需求,你有一个处理错误的单一库,但是你希望该库知道源是否为web、console、winforms等?
您可以利用库中的属性,例如枚举类型,来跟踪使用应用程序的类型。例如...
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.WinForm);
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Web);
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Console);
编辑
来自评论中的Samir...
此外,您可以针对每种类型的应用程序都创建一个类,并在您的错误记录器库中实现相同的接口。
例如,在Web应用程序中,您将使用:
WebErrorLogger error = new WebErrorLogger();
在进行这个步骤之前,我建议您先审查一下设计,但我认为这是一个有趣的挑战,想看看是否能找到其他方法。
ASP.Net:检查HttpContext.Current不为空。您也可以查看System.Web.Hosting.ApplicationManager.GetApplicationManager(),但我不确定在Asp.net之外会发生什么。
Windows窗体应用程序:您可以尝试使用System.Windows.Forms.Application.OpenForms,这将返回任何打开的窗体。假设是一个Windows窗体应用程序永远不会没有任何窗体。此外,控制台应用程序也可以启动Win表单。
服务:不确定,但我想知道您是否可以检查进程的名称。必须还有一个Windows API,因为任务管理器显示进程是否为服务(至少在Vista上是这样)。
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
可以替换为 IMAGE_SUBSYSTEM_WINDOWS_GUI
,以检测是否为 GUI 应用程序而不是控制台。
Windows 中的服务通常将 'services.exe
' 作为它们的父进程,确定父进程的方法在 CodeProject 中有很好的描述。
ASP.NET 进程在名为 ASPNET 的特殊用户下运行,可以从 访问令牌 中获取用户名。