2013-03-15 7 views
5

mio codice C# utilizza la rappresentazione chiamando funzioni Win32 tramite P/InvokePerché l'eccezione del codice rappresentato non viene rilevata?

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; 
} 

anche io ho AppDomain.CurrentDomain.UnhandledException gestore installata che registra anche tutti un'eccezione non gestita.

Sono sicuro che il codice che registra le eccezioni funziona bene con e senza rappresentazione.

Ora il problema è che nel codice precedente sembra che catch non sia stato immesso e anche UnhandledException non venga chiamato. L'unica traccia dell'eccezione è una voce nel Visualizzatore eventi.

Se posso aggiungere un finally come questo:

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

quindi l'eccezione viene registrato bene sia da catch e dalle UnhandledException gestore.

Cosa sta succedendo? Il thread che viene impersonato impedisce la normale gestione delle eccezioni?

+0

se si inserisce un punto di interruzione in 'LogException': ci si arriva? –

+0

@MarcGravell: non lo so, non ci sono debugger in cui questo viene riprodotto. Mi rendo conto che potrebbe esserci qualche problema con 'LogException()' stesso, ma finora il codice su cui si basa funziona bene sia impersonato che non impersonato. – sharptooth

+0

Ecco una supposizione: dato che .NET tiene traccia del contesto di esecuzione, la gestione delle eccezioni potrebbe rendersi conto che il contesto è cambiato e impedisce l'esecuzione del gestore delle eccezioni a meno che il ripristino non venga eseguito per primo. In caso contrario, si otterrebbe un elevazione dei privilegi se il codice dovesse essere eseguito con l'utente rappresentato ... –

risposta

3

Senza vedere il codice di LogException, non posso esserne sicuro, ma potrebbe essere che qualunque cosa tu stia facendo lì lo faccia nel contesto dell'utente impersonato/connesso e che quell'utente non ha utente diritti di fare qualunque cosa tu stia facendo, ad es scrivendo su un file ecc. e che il codice si blocchi in quel punto. Il fatto che il tuo codice funzioni solo dopo aver "Reverted to Self" sembra confermarlo.

Quindi quello che sto cercando di dire, è probabile che il vostro eccezione viene effettivamente catturato dalla cattura, ma che il LogException sta fallendo a causa di essa cercando di fare il lavoro in un contesto di un utente non corretta.

Per verificarlo, all'interno di LogException, provare a forzare il contesto corrente su "Sé" prima di tentare qualsiasi accesso e vedere se il primo frammento ora inizia a funzionare.

1

Risulta il problema era con il codice di registrazione. Ad un certo punto abbiamo aggiunto il codice che recupera l'ora di inizio del processo corrente (Process.StartTime) e che il codice restituisce Access denied quando viene chiamato da un thread rappresentato.

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 

codice di registrazione chiamato anche System.Diagnostics.Trace.WriteLine()prima invocare codice con Process.StartTime e scrive per "listener di analisi" riuscita, scrive soltanto attraverso quest'ultimo il codice non è riuscita.

Quindi non c'è differenza nell'ottenere eccezioni con o senza rappresentazione. È persino possibile installare un filtro di eccezioni in modo che venga richiamato nel contesto di sicurezza del codice rappresentato che può comportare l'elevazione dei privilegi. Details for the latter here.