Visual Studio “Zombie Mode”
Se state sviluppando un’estensione per Visual Studio dovete tenere in considerazione uno scenario decisamente poco documentato…mannaggia a loro
Durante il processo di startup dell’IDE c’è un periodo di tempo (lo Zombie Mode) in cui non potete interagire con l’IDE, come fare quindi a sapere lo stato dell’IDE? Non è proprio immediato… diciamo che avete una ToolWindow in cui avete bisogno di visualizzare informazioni (more to come…) relative allo stato dell’IDE quello che potete fare è:
[Guid( "2f48535f-40c3-45af-bdb1-b4860982d508" )] public class MyToolWindowPane : ToolWindowPane, IVsShellPropertyEvents
- Registrare la vostra ToolWindow come qualcuno che è in grado di ricevere eventi relativi alla variazione delle proprietà dell’IDE, implementando l’interfaccia IVsShellPropertyEvents:
public int OnShellPropertyChange( int propid, object var ) { }
- e specificando in fase di inizializzazione della ToolWindow che volete essere “avvisati”:
In fase di inizializzazione verifichiamo se siamo in “Zombie Mode”, se siamo in Zombie Mode ci registriamo per la notifica delle variazioni di valore delle proprietà dell’IDE altrimenti semplicemente procediamo con la nostra inizializzazione.protected override void Initialize() { base.Initialize(); var shellService = GetService( typeof( SVsShell ) ) as IVsShell; if( shellService != null ) { Object zm; var result = shellService.GetProperty( ( int )__VSSPROPID.VSSPROPID_Zombie, out zm ); var zombieMode = ( Boolean )zm; if( zombieMode ) { ErrorHandler.ThrowOnFailure( shellService.AdviseShellPropertyChanges( this, out cookie ) ); } else { this.FinishInitialization(); } } }
Per determinare la variazione dello Zombie Mode possiamo fare così:
Il metodo OnShellPropertyChange viene chiamato dall’IDE per ogni proprietà il cui stato varia, l’IDE ci passa l’id della proprietà e il valore corrente, quindi se la proprietà è quella che ci interessa e il valore è passato a false significa che non siamo più in Zombie Mode quindi:uint cookie; public int OnShellPropertyChange( int propid, object var ) { if( ( int )__VSSPROPID.VSSPROPID_Zombie == propid ) { if( ( bool )var == false ) { var shellService = GetService( typeof( SVsShell ) ) as IVsShell; if( shellService != null ) { ErrorHandler.ThrowOnFailure( shellService.UnadviseShellPropertyChanges( this.cookie ) ); } this.cookie = 0; this.FinishInitialization(); } } return VSConstants.S_OK; }
- ci deregistriamo dalle notifiche;
- completiamo il processo di inizializzazione;
Il tentativo di recuperare un’istanza dell’IDE in Zombie Mode fallisce e GetService ritorna null, in questo modo siamo invece sicuri che la chiamata venga fatta nel momento corretto.void FinishInitialization() { var dte = this.GetService( typeof( SDTE ) ) as DTE; }
.m