2013-03-15 11 views
5

मेरे सी # कोड पी के माध्यम से Win32 कार्यों को फोन करके प्रतिरूपण का उपयोग करता है/आह्वानप्रतिरूपित कोड से अपवाद क्यों नहीं पकड़ा गया है?

internal class Win32Native 
{ 
    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern int ImpersonateLoggedOnUser(IntPtr token); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern int RevertToSelf(); 
} 

try { 
    var token = obtainTokenFromLogonUser(); 
    Win32Native.ImpersonateLoggedOnUser(token); 
    throw new Exception(); // this is for simulation 
    Win32Native.RevertToSelf() 
} catch(Exception e) { 
    LogException(e); 
    throw; 
} 

भी मैं AppDomain.CurrentDomain.UnhandledException हैंडलर स्थापित है कि यह भी सभी बिना क्रिया का अपवाद लॉग की है।

मुझे यकीन है कि अपवाद लॉग इन करने वाला कोड प्रतिरूपण के साथ और बिना दोनों ठीक काम करता है।

अब समस्या यह है कि उपरोक्त कोड में यह catch दर्ज नहीं किया गया है और UnhandledException भी नहीं कहा जाता है। अपवाद का एकमात्र निशान इवेंट व्यूअर में एक प्रविष्टि है।

अगर मैं एक finally इस तरह जोड़ें:

try { 
    var token = obtainTokenFromLogonUser(); 
    Win32Native.ImpersonateLoggedOnUser(token); 
    try { 
     throw new Exception(); // this is for simulation 
    } finally { 
     Win32Native.RevertToSelf() 
    } 
} catch(Exception e) { 
    LogException(e); 
    throw; 
} 

तो अपवाद दोनों catch से और UnhandledException हैंडलर से ठीक लॉग होता है।

क्या हो रहा है? क्या थ्रेड का प्रतिरूपण सामान्य अपवाद हैंडलिंग को रोकता है?

+0

यदि आप 'LogException' पर ब्रेक-पॉइंट डालते हैं: क्या आप वहां जाते हैं? –

+0

@MarcGravell: मुझे नहीं पता, वहां कोई डीबगर नहीं है जहां इसे पुन: उत्पन्न किया जाता है। मुझे एहसास है कि 'LogException()' के साथ कुछ समस्या हो सकती है, लेकिन अब तक जिस कोड पर निर्भर करता है वह दोनों प्रतिरूपित और प्रतिरूपित नहीं है। – sharptooth

+0

यहां अनुमान लगाते हुए: चूंकि .NET निष्पादन संदर्भ का ट्रैक रखता है, इसलिए अपवाद हैंडलिंग का एहसास हो सकता है कि संदर्भ बदल गया है और अपवाद हैंडलर को तब तक निष्पादित करने से रोक रहा है जब तक कि वापस पहले निष्पादित नहीं किया जाता है। अगर ऐसा नहीं किया जाता है तो कोड को प्रतिरूपित उपयोगकर्ता के साथ चलाने के लिए विशेषाधिकारों की उन्नति होगी ... –

उत्तर

3

LogException के कोड को देखे बिना, मुझे यकीन नहीं है, लेकिन यह हो सकता है कि आप जो भी कर रहे हैं वह प्रतिरूपित/लॉगऑन उपयोगकर्ता के संदर्भ में ऐसा कर रहा है और उस उपयोगकर्ता के पास उपयोगकर्ता नहीं है ऐसा करने का अधिकार जो भी हो रहा है उदाहरण के लिए एक फ़ाइल आदि को लिखना और उस बिंदु पर कोड उस बिंदु पर दुर्घटनाग्रस्त हो जाता है। तथ्य यह है कि आपका कोड केवल "स्वयं को वापस करने" के बाद ही काम करता है, ऐसा लगता है।

तो मैं इसे कहने की कोशिश कर रहा हूं, संभावना है कि आपका अपवाद वास्तव में पकड़ से पकड़ा जा रहा है, लेकिन गलत उपयोगकर्ता के संदर्भ में काम करने की कोशिश करने के कारण LogException विफल हो रहा है।

अपने लॉगएक्सप्शन के अंदर, इसका परीक्षण करने के लिए, किसी भी लॉगिंग का प्रयास करने से पहले अपने वर्तमान संदर्भ को "स्वयं" पर बल दें और देखें कि पहला स्निपेट अब काम करना शुरू कर रहा है या नहीं।

1

लॉगिंग कोड के साथ समस्या को हल करता है। किसी बिंदु पर हमने कोड जोड़ा जो वर्तमान प्रक्रिया प्रारंभ समय (Process.StartTime) पुनर्प्राप्त करता है और उस कोड को प्रतिरूपित धागे से बुलाए जाने पर Access denied उत्पन्न होता है।

Access is denied 
System.ComponentModel.Win32Exception 
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited) 
at System.Diagnostics.Process.GetProcessTimes() 
at System.Diagnostics.Process.get_StartTime() 
//our logging code here 

लॉगिंग कोड भी System.Diagnostics.Trace.WriteLine()बुलाया से पहले Process.StartTime साथ कोड लागू और "ट्रेस श्रोताओं" सफल के माध्यम से लिखता है, केवल के माध्यम से बाद के कोड में विफल रहा है लिखता है।

तो प्रतिरूपण के साथ या बिना अपवादों को पकड़ने में कोई अंतर नहीं है। एक अपवाद फ़िल्टर स्थापित करना भी संभव है ताकि इसे प्रतिरूपित कोड के सुरक्षा संदर्भ में बुलाया जा सके जो संभावित रूप से विशेषाधिकार उन्नयन में हो सकता है। Details for the latter here

संबंधित मुद्दे