2013-06-19 9 views
6

Questa domanda non riguarda il riavvio di un'applicazione. Lo sto già ottenendo utilizzando un Mutex e un'applicazione di avviamento secondaria. Ho dovuto ricorrere a ciò dopo aver affrontato alcuni problemi usando Application.Restart.Come funziona Application.Restart in .NET?

In ogni caso, non essendo fluente con IL, mi chiedevo se qualcuno potesse spiegare come funziona Application.Restart in primo luogo. È una chiamata al runtime, ma cosa fa esattamente il runtime? Come chiude l'istanza esistente e come fa a sapere quando lanciarne una nuova?

risposta

8

... non essere fluente con IL, ...

Hai pensato di usare un decompiler (Reflector, dotPeek) o, meglio ancora, il codice del framework .NET reference source?

In ogni caso.

Ad un look casual che fa il seguente:

  • In tutti al di sotto dei casi, l'istanza corrente è terminato con Application.ExitInternal(). Questo è il succo del metodo pubblico Application.Exit(), che elimina alcuni controlli/asserzioni di sicurezza.

  • Verificare se è possibile determinare lo Assembly.GetEntryAssembly(). Se si tratta di null la chiamata al numero Application.Restart() è stata eseguita molto probabilmente dal codice non gestito e l'operazione genera un NotSupportedException per il chiamante.

  • Verificare se il processo corrente è ieexec.exe, in tal caso utilizzarlo per riavviare l'applicazione (per ulteriori informazioni su ieexec.exe, vedere here). In realtà si tratta anche di una chiamata Process.Start() a ieexec.exe, ma gli argomenti della riga di comando non vengono raccolti da Environment.GetCommandLineArgs() (vedi sotto), ma leggendo i dati del dominio dell'applicazione APP_LAUNCH_URL.

  • Verificare se l'applicazione è un'applicazione click-once (ApplicationDeployment.IsNetworkDeployed), in tal caso chiamare un codice nativo interno CLR per (ri) avviare quello: CorLauncApplication. L'unico codice sorgente pubblicamente disponibile che assomiglia in qualche modo alle parti native del CLR è la CLI di origine condivisa (sscli), che è basata sul framework .NET 2.0 ed è parzialmente incompleta. Contiene una definizione per quella funzione (clr\src\vm\hosting.cpp), ma è solo uno stub. Alla fine userà alcuni mezzi per riavviare il processo (ad esempio l'API CreateProcess di Win32).

  • Altrimenti: l'applicazione è un'applicazione .NET "normale". Environment.GetCommandLineArgs() viene utilizzato per ricreare la riga di comando originale e Process.Start(Application.ExecutablePath) viene utilizzato per riavviare l'applicazione.

L'uso del Application.Exit -mechanism per cercare di porre fine l'istanza corrente è probabilmente la ragione per cui a trovarlo inaffidabile. I moduli che annullano l'evento di chiusura dell'invio possono interromperlo. Vedi anche domanda this SO.

+0

Bah, la tua risposta è molto migliore della mia, potrei anche eliminare il mio :(. +1 a te buon signore! –

+0

@ Christian.K: Chi chiama il 'Process.Start (Application.ExecutablePath)' ? – joe

+0

@joe Il thread che ha chiamato 'Application.Restart()' è l'ultima cosa che fa la funzione prima che ritorni. –

Problemi correlati