Ich habe einige IO-Code, der einen Stream in einem try. catch liest. Es fängt IOException und ruft System. Runtime. InteropServices. Marshal. GetHRForException () innerhalb des catch, in einem Versuch, verschiedene Aktionen auf der Grundlage der HResult zu nehmen. So etwas wie dieses: Aber diesen Code innerhalb von ASP mit Vertrauenswürdigkeit ausführen, bekomme ich diese Ausnahme: Ein paar Fragen: Ich denke, die Ausnahme ist aufgetreten, weil GetHRForException in unmanaged Code aufruft, was in mittlerem Vertrauen nicht erlaubt ist. Korrigieren Diese Ausnahme wird ausgelöst, nicht zum Zeitpunkt der Ausführung von GetHRForException, aber zum Zeitpunkt der Methode wird JITed - Correct (Die stacktrace zeigt meine Methode, aber ich bin sicher, dass eine IO-Ausnahme nicht aufgetreten ist) Wenn ja, Gibt es einen Weg für mich, das Verhalten in einer partiellen Vertrauensumgebung zu variieren, so dass ich nicht die GetHRForException (nicht verwalteter Code) anrufe, wo es nicht erlaubt ist. Mit anderen Worten, wie kann ich dem JIT erlauben, bei der Kompilierung Zeit zu sein, während auch Auswertung zur Laufzeit, ob der Code GetHRForException () anrufen soll So etwas wie das: Ich denke, es gibt einen Runtime-Mechanismus zum Testen, ob Berechtigungen zur Verfügung stehen, aber nicht in der Lage waren, ihn zu finden. BEARBEITEN Ist dieser Blog Artikel die Antwort ShawnFa von Microsoft sagt, dass Sie nicht versuchen können. Catch (SecurityException) um eine Methode, die durch einen LinkDemand geschützt ist. Wenn methodA () methodB () aufruft und methodB () mit LinkDemand für volles Vertrauen markiert ist, wird der LinkDemand mit MethodA überprüft. Deshalb, um die SecurityException zu vermeiden, muss ich Marshal. GetHRForException in eine separate Methode extrahieren. Ist das richtig Angewendet auf meinen Code, MethodA () könnte der Code sein, der anruft, und dann in den Fang versucht, GetHRForException () aufzurufen. GetHRForException ist MethodB (). Der LinkDemand wird ausgewertet, wenn MethodA () JITD ist. (Diese LinkDemand scheitert in meinem Medium-Vertrauen ASP-Szenario). Wenn ich die GetHRForException in eine neue Methode, MethodC () verschreibe und methodC () nur nach einer zwingenden Erlaubnis aufgerufen habe, kann ich die SecurityException in JIT-Zeit vermeiden, da methodC () sein wird JITD erst nach der Erlaubnis. Demain () gelingt. Fragte 12. Juli 09 um 14:20 Die Methode erforderlich ist SecurityPermission. IsUnrestricted (). Es gibt ein wahres oder falsches Zeugnis an, ob die Berechtigung erlaubt ist oder nicht. Es verlangt keine Genehmigung, wie auch SecurityPermission. Demand (). Ich benutze IsUnresticted mit SecurityPermissionFlag. UnmanagedCode, um zu sehen, ob die Assembly darf nicht verwalteten Code aufrufen, und rufen Sie dann den nicht verwalteten Code nur, wenn erlaubt. Es gibt eine zusätzliche Torsion. Der JIT-Compiler, beim Kompilieren einer Methode, prüft auf CodeAccessPermission LinkDemands auf jede Methode namens my die Methode, die kompiliert werden soll. Marshal. GetHRForException () ist mit einem LinkDemand markiert. Daher wird meine Methode, die Marshal. GetHRForException () aufruft, eine unschlagbare SecurityException zum Zeitpunkt des JIT-Kompilierens auslösen, wenn sie in einer eingeschränkten Umgebung laufen, wie ASP mit mittlerem Vertrauen. Deshalb müssen wir die Methode, die Marschall. GetHRForException () in diesem Fall anruft, niemals jITEN, was bedeutet, dass ich Marschall. GetHRForException () in eine separate Methode in meinem Code, der gerade aufgerufen wird, wenn UnmanagedCode aufgerufen wird, auslösen muss uneingeschränkt. Heres ein Beispiel Code: beantwortet Jul 20 09 um 17:56 Ja - Medium Vertrauen erlaubt keine Anrufe in nicht verwalteten Code. Die einzige Vertrauensstufe, die es erlaubt, ist voll Vertrauen. Es hängt davon ab, ob. CAS-Forderungen können zur Laufzeit stattfinden, aber die Hosting-Umgebung kann auch auf Wanderung und auf der Suche nach Sachen, die es nicht tun kann. Sie können testen, um zu sehen, ob Sie einen Anruf zu nicht verwaltetem Code unter Verwendung einer CAS-Nachfrage mit einer Instanz von SecurityPermission machen können. Der Code, um eine CAS-Nachfrage zu machen, sieht so aus, wie dies beantwortet wurde. Jul 12 09 um 14:32 OK, das ist super Info. Dies deckt den Teil b des Q3 ab. Aber was ist mit Teil a wie bekomme ich die JIT kompilieren, um erfolgreich zu sein Kann ich meine Methode mit einem Sicherheitsattribut markieren oder. Denken Sie daran, meine Theorie ist, dass der SecurityPermission-Fehler nicht zur Laufzeit passiert, es geschieht während JIT - und ich glaube, Sie haben bestätigt, dass dies möglich ist. Also die Frage ist, wie schreibe ich den Code, damit der JIT kompilieren kann. Ndash Cheeso Jul 12 09 um 15:50 Es sollte zur Laufzeit geschehen, sonst würde die Montage gar nicht geladen werden - und dafür muss die Montage als Genehmigung markiert werden. Sogar dann ist das oft ein Runtime-Check, wie es bei der Montage der Last passieren wird, was zur Laufzeit sein könnte. Ndash blowdart Jul 12 09 at 16:24 Verschiedene Art von Check, Link-Anforderungen sind Attribute auf eine Methode, und sind in der Tat überprüft bei JIT Zeit. Es ist ziemlich viel von dem Rahmen selbst verwendet und es ist selten, es außerhalb der CLR-Quelle zu sehen. Was ich demonstriere ist eine zwingende Forderung, nicht eine deklarative wie eine SecurityPermission (SecurityAction. LinkDemand, Unrestricted true) ndash blowdart Jul 12 09 bei 18: 55Marshal. GetHRForException tut mehr als nur Get-HR-For-Exception Let8217s zuerst anfangen zu suchen Bei einem kleinen Code-Snippet: Das sieht ganz gut aus, richtig nicht wirklich. Es stellt sich heraus, diese API ist eigentlich schlecht benannt, und es tatsächlich mehr als nur das Abrufen der HR aus dem Exception-Objekt. Mit dieser API falsch könnte Ihnen einige seltsame Probleme, wie das Auswerfen einer falschen, alten Ausnahme. Also, was macht die API eigentlich tun Neben der Rückkehr der HRESULT, diese Funktion setzt auch das aktuelle Thread IErrorInfo Objekt als das Exception-Objekt sein. Jeder Thread hat ein assoziiertes IErrorInfo COM-Objekt, das standardmäßig auf NULL basiert. Dieses IErrorInfo-Objekt repräsentiert den Fehler des letzten COM-API-Aufrufs, der wie die GetLastError () Win32-API oder errno C api ist. Aus dem IErrorInfo-Objekt können Sie weitere Informationen wie die Fehlerbeschreibung, den Hilfedatei-Kontext usw. erhalten, der Ihnen weitere Informationen über den Fehler gibt. Durch das Setzen von IErrorInfo-Objekt auf das Exception-Objekt (eigentlich Einstellung auf die IErrorInfo-Implementierung des Exception-Objekts, das von allen verwalteten Objekten gemeinsam genutzt wird), erzählst du im Wesentlichen deine COM-Anrufer, quothey, es ist ein Fehler, it8217s dieses Exception-Objekt und Sie sollten etwas über itquot tun, was offensichtlich eine schlechte Idee ist, wenn Sie nur den HR abrufen möchten. In vielen Fällen könnte dies unbemerkt bleiben, wenn deine COM Callercallee IErrorInfo richtig behandelt. Ich kenne, dass sie dem COM IErrorInfo-Protokoll folgen, was grundsätzlich ist: 1. Der Anrufer benutzt IErrorInfo aus dem aktuellen Thread beim Aufruf einer COM-Schnittstelle, die explizit sagt, dass ich IErrorInfoquot 2 unterstützt habe. Der Anklang (der die COM-Schnittstelle implementiert), der sagt Ich benutze IErrorInfoquot, muss IErrorInfo löschen, bevor ich zurückkehre. Dies ist sehr ähnlich zu GetLastError () errno, rechts Wenn dies der Fall ist, wird das falsch eingestellte IErrorInfo im Thread typischerweise entweder von einer Schnittstellenimplementierung, die IErrorInfo unterstützt oder ignoriert, überschrieben. Allerdings, weil das Protokoll, das ich beschrieben habe, ist eigentlich nicht sehr gut verstanden von jedem COM-Entwickler, I8217ve oft gesehen Fälle, in denen die COM-Komponente nur sagen, quotenure, ich unterstütze IErrorInfo auf jedem COM Interfacequot, und sie don8217t setclear IErrorInfo überhaupt. Und dann, der Anrufer dieser schlecht implizierten COM-Schnittstelle, würde am Ende mit dem IErrorInfo-Set von GetHRForException-Aufruf früher, und ist zu glauben, dass es einen Fehler gibt. Zum Beispiel, let8217s betrachten das folgende Szenario: Einige COM-Komponente A Anrufe in Code-Code werfen eine Ausnahme, sagen IOException Code fängt die Ausnahme, und rufen Sie Marshal. GetHRForException, die IErrorInfo auf diese Ausnahme IOException Code Anrufe in eine andere COM-Komponente B, Anrufe setzt In IB. Func IB. Func fehlgeschlagen und gibt einige HR-Fehler-Code, sagen EOUTOFMEMORY CLR sieht die HR-Fehler-Code, und fragen Sie die COM-Komponente B quotdo Sie unterstützen IErrorInfoquot, und B Antworten quotsure, warum notquot, außer es doesn8217t wirklich unterstützen es und Es doesn8217t setclear IErrorInfo CLR holt den IErrorInfo ab und sieht, dass es tatsächlich eine verwaltete Ausnahme ist und die IOException-Ausnahme anstelle von OutOfMemoryException auslöst. Jetzt können Sie sich fragen: Was ist diese API wirklich für den ersten Platz gedacht Es ist eigentlich an Orten in COM Interop verwendet, wo Sie die HRESULT zurückgeben und IErrorInfo selbst setzen wollen. Dies geschieht nicht sehr oft 8211 die meisten Leute würden glücklich genug sein, um COM Interop kümmert sich um diesen Teil durch die Umwandlung von Exception in HR und IErrorInfo (was passiert, um Marshal. GetHRForException aufrufen). Also, wenn du nicht wirklich weißt, was du tust, mein Rat ist, weg von Marschall zu bleiben. GetHRForException. Was, wenn Sie wirklich, wirklich wollen, um nur die HRESULT für eine bestimmte Ausnahme Sie sollten Exception. HResult Eigenschaft verwenden.
No comments:
Post a Comment