.Net: Application.Exit macht nicht das, wofür es da ist...
Noodles
- sonstiges
0 Dragon0 Frank (no reg)0 Noodles
Hallo Freunde der microsoftschen Technologien,
ich habe hier ein Problem vorliegen, dass mich im Moment an der guten Welt zweifeln lässt: Ich nehme eine Sicherheitsabfrage bei der Initialisierung einer Windows.Forms-Anwendung vor. Wenn der Benutzer nicht die benötigten ActiveDirectory-Rollen besitzt, dann soll nach einer Fehlermeldung das Programm verlassen werden. So weit, so schlecht. Hier der Codeausschnitt:
If Not Security.IsAllowEntrance Then
MsgBox("Sie haben nicht bla bla bla.")
Application.Exit()
End If
Das sollte ja eigentlich das Programm dazu bewegen die Verarbeitung abzubrechen. Tut´s aber leider nicht. Es kommt die Fehlermeldung (ist also korrekterweise in die If-Abfrage gesprungen), aber das Programm wird danach ganz normal gestartet. Auch Me.Close und MyBase.Close haben keinerlei Auswirkung. Ich beende das Programm jetzt über den Hammer "System.Threading.Thread.CurrentThread.Abort()".
Aber kann mir jemand sagen, was plötzlich hier passiert ist?? Lasst mich bitte nicht dumm sterben!
Grüße und schon mal vielen Dank Noodles
Hallo auch,
Meiner bescheidenen Ansicht nach gehört das "Application.Exit()" nicht in die if-schleife sondern in den Form_handler ( aktion des OK_Button ) der erzeugten MSG_Box.
mfg
Das Schmunzelmoster
Hi Dragon und Schmunzelmonster...,
danke für deine schnelle Antwort. Diese Messagebox wird als Default nur mit OK-Button dargestellt und egal welche Aktion der User tätigt, wird nach Wegdrücken der Box die Anwendung beendet. Und ich sehe ja auch im Debugger, dass er die Methode ausführt. Bis gestern abend hat er ja auch alles beendet und aufgeräumt. Und glaubts mir oder auch nicht: Ich habe wirklich nichts geändert *g*
Auf einen Form_Handler der MessageBox kann man in .Net meines Wissens nicht direkt zugreifen (müsste ich mal probieren). Es gibt aber einen Rückgabewert, der mir sagt, was der User getan hat.
Grüße Noodles
Hallöchen
danke für deine schnelle Antwort. Diese Messagebox wird als Default nur mit OK-Button dargestellt und egal welche Aktion der User tätigt, wird nach Wegdrücken der Box die Anwendung beendet. Und ich sehe ja auch im Debugger, dass er die Methode ausführt. Bis gestern abend hat er ja auch alles beendet und aufgeräumt. Und glaubts mir oder auch nicht: Ich habe wirklich nichts geändert *g*
Büdde, hmm das klingt dann schon recht seltsam.
So rein aus dem Bauch raus würde ich mal versuchen den Rechner ganz neu zu starten. Womöglichist bei Deiner "Hammer_close_methode" doch irgend ein Handle über geblieben. Ist nur ne vermutung, vieleicht hilfts ja.
mfg
Das Schmunzelmonster
Hi,
Büdde, hmm das klingt dann schon recht seltsam.
äußerst seltsam...
ich denke mich hat VS.Net 2003 pünktlich zum Start von VS.Net 2005 sanft darauf aufmerksam gemacht, dass ich doch bitte einen Upgrade vornehmen soll. Das Starten einer Solution braucht jetzt ca. 3 Minuten und es wird plötzlich kein Event mehr beim Ändern eines Listeneintrags geworfen. Jetzt wirds langsam haarig. Nur kann ich nicht umsteigen, da mein Betrieb den Umstieg auf Version 2.0 erst in ein paar Wochen vornehmen kann bzw. will. Bleibt mir wahrscheinlich nur die Neuinstallation oder das Aussitzen.
Schaun mr´ mal
Grüße Noodles
Hi,
du solltest evt. mal den Code der gesamten WinForm Klasse posten.
Nur von dem kurzen Ausschnitt kann man keine wirklich Aussage über
das Fehlverhalten treffen.
Ciao, Frank
Hi Frank,
das widerum ist jetzt leider nicht möglich, da 1995 Zeilen hier drin den Rahmen etwas sprengen würden und mein Cheffe mir dann den Kopf abreißt... Aber ich denke, es ist auch unerheblich, was im genau im Code steht. Wichtig ist, dass weder Application.Exit(), noch Me.Close(), noch MyBase.Close() das Programm beenden. Ich habe diese Statements in dutzenden Programmen schon eingesetzt, aber wie gesagt seit gestern gehts nicht mehr. Und ich sehe, dass im Debugger diese Methoden nacheinander aufgerufen werden. Normalerweise ist schon nach der ersten Schluss. Ich rechne eher damit, dass Visual Studio mir diese Streiche spielt.
Hier aber nochmal der relevante Codeabschnitt:
Dim Sec As New Security
If Not Sec.IsAllowEntrance Then
MsgBox("...")
Application.Exit()
Me.Close() ' <-- hier dürfte das Programm nie hinkommen
MyBase.Close()
Try
System.Threading.Thread.CurrentThread.Abort()
Catch
End Try
End If
Ich werde VS neu installieren und solange behelfe ich mir mit Thread.Abort() oder lasse meine Kollegen den Code kompilieren *g*
Grüße Noodles
Hi,
dann keine Hilfe auch nur beschränkter Natur sein. (BTW: du könntest mich bei Bedarf direkt für einen Code Review "engagieren", Vertraulichkeit für den gereviewten Sourcecode dann natürlich garantiert.) Ich bezweifle, dass die Installation des Visual Studios etwas an deinem Problem ändern könnten.
Wenn du sagst, das Me.Close() usw. auch nicht funktionieren ...
Welche Events deiner Formularklasse haben einen Subscriber?
.Closing eventuell? Oder ist das Formular evt. nicht über die Applikation aufgerufen? Also via Application.Run(new Form1()) oder nicht? Wer erzeugt die Instanz deines Formular? Wer zeigt es wann an? Wie (von wem und wann) wird deine Sicherheitsabfrage ausgelöst. Ich nehme mal an, dass sie innerhalb einer Methode abläuft? Oder gar im Konstruktor [sowas macht man aber nicht]?
Application.Exit() führt u.a. die Methode .Close() auf der zugehörigen Form-Klasse aus, welche das Ereignis Form.Closing auslöst.
Als weiteren Tipp könnte ich dir geben, mach einfach ein ganz simples neues WinForm-Projekt auf (das kann man ja danach wieder löschen) und versuche Application.Exit() oder Me.Close() darin auszuführen. Und zwar ohne irgendwie irgendwas anderes da zu machen. Keine Aktionen im Designer!
Ciao, Frank
Hi,
dann keine Hilfe auch nur beschränkter Natur sein. (BTW: du könntest mich bei Bedarf direkt für einen Code Review "engagieren", Vertraulichkeit für den gereviewten Sourcecode dann natürlich garantiert.)
dafür müsste meine Firma Geld springen lassen und als GL würde ich auch nichts bezahlen, was meine Untergebenen nicht auch anderweitig lösen können. Aber vielen Dank fürs Angebot. Es wird bestimmt die Eine oder Andere Situation kommen, wo bei uns das Latein am Ende ist.
.Closing eventuell?
Oder ist das Formular evt. nicht über die Applikation aufgerufen? Also via Application.Run(new Form1()) oder nicht?
Es wird tatsächlich über Application.Run(New frmAdminUser) gestartet. MyBase.Closing wird nicht abgefangen, aber ich habe es jetzt getestet. Es geht in die Methode, aber egal wie ich das Cancelelement behandle, die Form wird nicht beendet.
Wie (von wem und wann) wird deine Sicherheitsabfrage ausgelöst. Ich nehme mal an, dass sie innerhalb einer Methode abläuft? Oder gar im Konstruktor [sowas macht man aber nicht]?
Zu meiner Schande muss ich gestehen, dass ich das bisher nach der Initialisierung der Komponenten in einer Methode ausführe, die im Konstruktor aufgerufen wird. Macht man das besser in der Form_Load? Oder ganz anders?
Als weiteren Tipp könnte ich dir geben, mach einfach ein ganz simples neues WinForm-Projekt auf (das kann man ja danach wieder löschen) und versuche Application.Exit() oder Me.Close() darin auszuführen. Und zwar ohne irgendwie irgendwas anderes da zu machen.
Andere Formulare sind nicht betroffen. Da hätte ich aber auch früher drauf kommen können das auszutesten. Ich habe hier nur das Problem, dass ich keine WindowsForm erstellen kann. Ich bekomme dann die aussagekräftige Fehlermeldung "Unbekannter Fehler". Also geht der erfinderische Schwabe her und erstellt eine normale Klasse und fügt eine vorgefertigte Default-WinForm ein *g*. Soweit zu meinem VS.Net.
Auf gut deutsch: In den Weiten meines Codes liegt noch etwas im Argen. Das werde ich mal überarbeiten. Vielen Dank für deine super Hilfe!
Grüße Noodles
Hallo nochmal,
du solltest in der Tat die Abfrage nicht im Konstruktor ablaufen lassen, generell sollte man keine intensiveren Operationen externer Komponenten innerhalb eines Klassen-Konstruktors ablaufen lassen. Ein Grund ist, dass zu dem Zeitpunkt die Klasse auch noch nicht wirklich existiert. Z.b. werden Events noch nicht registriert.
Der .Load Event ist für soetwas besser geeignet.
Darüber hinaus brauchst du Application.Run nicht mit einem "new MyForm" füttern, du kannst auch eine fertig aufgebautes Formular nehmen und unzählig viel vor dem System.Windows.Forms.Application.Run() durchführen, wie eben Sicherheitschecks ...
In deinem Fall soll sich die "Application" in der Durchführung ihrer .Run Methode auch gleich wieder mittels .Exit beenden. Ich denke, dass da der Hase bei dir im Pfeffer liegt.
<quote from msdn>
Application.Exit: Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.
</quote>
Ich stelle gerade fest, dass ich mich hinsichtlich einer Sache geirrt hatte, Application.Exit schliesst zwar alle Fenster, aber die Events .Closing und .Closed werden dabei nicht ausgelöst.
Grüße, Frank
Hallo nochmal,
ebenso,
man sollte es nicht glauben, aber ich mache Feierabend. Meine Kollegen werden mich als Halbzeitkraft beschimpfen, aber irgendwann reicht die Fehlersuche. Ich habe zu Hause leider kein VS.Net, aber ich werde das am Montag umschreiben, so dass die Überprüfungen im Form_Load abgehandelt werden.
Z.b. werden Events noch nicht registriert.
Das kann aber auch ein Vorteil sein...
In deinem Fall soll sich die "Application" in der Durchführung ihrer .Run Methode auch gleich wieder mittels .Exit beenden. Ich denke, dass da der Hase bei dir im Pfeffer liegt.
na das werden wir am Montag sehen
Ich stelle gerade fest, dass ich mich hinsichtlich einer Sache geirrt hatte, Application.Exit schliesst zwar alle Fenster, aber die Events .Closing und .Closed werden dabei nicht ausgelöst.
und soll ich dir was sagen? Ich habe vorher das Event eingebaut und es wird definitiv bei Application.Exit geraised. Mein Rechner und ich sind halt ein bißchen anderes, als der Rest der Menschheit.
Schönes Wochenende und dank dir für deine Mühe
Gruß Noodles