2009-05-18 11 views
4

Ich habe eine Bibliothek, die auf verschiedene Arten auf Ausnahmen reagieren muss, je nachdem, ob sie in einer Konsolenanwendung, WinForms, AspNet oder Windows Service ausgeführt wird. Ich habe experimentiert, verschiedene Eigenschaften in den Namespaces System.Windows.Forms und System.Web zu betrachten, aber ich finde keine zuverlässige Möglichkeit, genau zu erkennen, welche Art von Anwendung meine Bibliothek hostet. War schon mal jemand hier? Hat jemand eine zuverlässige Lösung?Wie erkennen Sie den .Net-Anwendungstyp?

+1

Die Lösung, die ich verwendet habe, kombiniert die Antworten von Arul und Josh, und diese Links: http://blogs.msdn.com/kstanton/archive/2004/03/31/105060.aspx, http: // www .codeguru.com/cpp/wp/system/misc/article.php/c2897. Also zuerst überprüfe ich, ob es einen ASP-Kontext gibt, wenn nicht, dann lade ich die Haupt-App-Binärdatei und überprüfe die Flags in der Kopfzeile, um zu sehen, ob sie auf die Windows- oder Konsolen-Subsysteme abzielt. Ich kann eine Codebeispiel liefern, wenn jemand interessiert ist. –

Antwort

3

Ich würde Ihr Design in Frage stellen, bevor Sie diesen Weg gehen, aber ich dachte, das wäre eine interessante Herausforderung und wollte sehen, ob ich trotzdem finden könnte.

ASP.Net: Überprüfen Sie, ob HttpContext.Current nicht null ist. Sie könnten sich auch System.Web.Hosting.ApplicationManager.GetApplicationManager() ansehen, aber ich bin mir nicht sicher, wie sich das außerhalb von Asp.net verhalten wird. Windows Forms: Sie könnten versuchen, System.Windows.Forms zu verwenden. Application.OpenForms, werden alle geöffneten Formulare zurückgegeben. Eine Annahme wird gemacht, dass eine Windows-Formularanwendung niemals irgendwelche Formen haben würde. Auch eine Konsolenanwendung kann ein Gewinnformular starten.

Service: Nicht sicher, aber ich frage mich, ob Sie den Namen des Prozesses überprüfen können.Es muss auch ein Windows-API sein, da der Task-Manager zeigt, wenn ein Prozess einen Dienst ist (zumindest auf Vista es tut)

+1

Seien Sie vorsichtig mit HttpContext.Current; In ASP.NET-Anwendungen werden keine Threads zurückgegeben, die nicht angefordert wurden. –

2

Das fühlt sich an, als ob man etwas mehr ins Design schauen möchte, ist aber spontan. Eine Klassenbibliothek sollte solche Dinge über ihren Aufrufer nicht wissen müssen.

Was möchten Sie im Ausnahmebehandlungsverhalten basierend auf dem Kontext ändern, in dem es ausgeführt wird?

Basierend auf Ihrem Kommentar, würde ich empfehlen, eine Schnittstelle für einen Fehlerbehandler zu definieren, und dann die erforderliche Anzahl von Implementierungen dieser Schnittstelle (eine für WinForms, eine für Konsole usw.) erstellen und den Client haben Anwendung erstellen und injizieren die entsprechende Implementierung in die Bibliothek. Auf diese Weise heben Sie den Wissensbedarf aus der Bibliothek heraus und verlagern die Verantwortung auf die Client-Anwendung. Diese Implementierungen können sich immer noch in Ihrer Klassenbibliothek befinden, die zu verwendende Entscheidung wird jedoch von der Clientanwendung getroffen.

+0

Es ist eine Support-Bibliothek, die Infrastruktur für andere Bibliotheken und Anwendungen bereitstellt, die in einer Vielzahl von Kontexten verwendet werden können. Die Idee ist, dass diese Bibliothek ein allgemeines Mittel zum Behandeln nicht behandelter Fehler und zum Melden an die Host-Anwendung bereitstellt. –

+0

In allen Fällen wird eine E-Mail mit Details an einen Jira-Server gesendet. In Windows wird jedoch ein Screenshot aufgenommen und dem Benutzer ein Dialog angezeigt. In Konsolen-Apps werden Details in die Konsole geschrieben. Ich habe die Fehlerbehandlung hier erwähnt, aber es kann auch andere Zwecke geben. –

+0

Ich habe meine Antwort als Antwort auf Ihren Kommentar aktualisiert –

5

Wenn ich verstehe, was Sie suchen, haben Sie eine einzelne Bibliothek, die Fehlerbehandlung durchführt, aber Sie möchten, dass die Bibliothek weiß, ob die Quelle Web, Konsole, Winforms usw. ist?

Möglicherweise können Sie eine Eigenschaft in der Bibliothek verwenden, z. B. eine Aufzählung, die den Typ der konsumierenden Anwendungen verfolgt. Zum Beispiel ...

ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.WinForm); 
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Web); 
ErrorLogger error = new ErrorLogger(ErrorLoggerAppType.Console); 

EDIT
Von Samir in den Kommentaren ...
Außerdem konnte man immer nur eine Klasse für jede Art von Anwendung hat die gleiche Schnittstelle in Ihrer Fehlerlogger Bibliothek implementieren .

Zum Beispiel in einer Web-Anwendung würden Sie verwenden:

WebErrorLogger error = new WebErrorLogger(); 
+1

Oder: error = new GUIErrorLogger();/error = new WebErrorLogger();/error = neu ConsoleErrorLogger(); wo sie alle die Schnittstelle ErrorLogger implementieren. –

+0

Das würde auch funktionieren ... – RSolberg

+0

Dies ist, wo ich im Moment bin - aber ich versuche, die Notwendigkeit für den Verbraucher zu beseitigen, auf diese Weise zu initialisieren. Wenn niemand eine bessere Idee hat, dann muss ich wohl dabei bleiben. –

3

Das klingt wie etwas, das am besten mit der Konfiguration behandelt würde. Vielleicht Injektion von etwas wie eine IExceptionHandler-Schnittstelle über ein IOC.

1
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 mit IMAGE_SUBSYSTEM_WINDOWS_GUI werden excahnged zu erkennen, ob es statt Konsole eine GUI-Anwendung ist.

Dienste in Windows haben in der Regel "services.exe" als ihre Eltern, die Art und Weise der Bestimmung der Elternprozess ist gut bei CodeProject beschrieben.

ASP.NET Prozess läuft unter speziellen Benutzer namens ASPNET, Name des Benutzers kann von an access token erhalten werden.

+0

Dies ist am nächsten zu dem, was ich versuche zu erreichen. Dieser Link scheint eine angemessene Menge an Informationen darüber zu liefern, ob eine Binärdatei eine Konsolenanwendung ist: http://www.codeguru.com/cpp/w-p/system/misc/article.php/c2897. Ich kann mich nicht darauf verlassen, dass der ASPNET-Benutzer verwendet wird - wir verwenden alle Arten von Dienstkonten für verschiedene Zwecke. Ich denke, in Verbindung mit Joshs Antwort unten kann ich wahrscheinlich einen vernünftigen Stoß auf eine Antwort finden. –

Verwandte Themen