Mettendo a confronto un progetto Windows Forms C#2.0 con lo stesso in VB 2005, appaiono subito delle divergenze sopratutto per quanto riguarda la parte di startup/shutdown dell'applicazione stessa.
Mentre in C# 2.0, a parte che, finalmente, l'entry point di un applicazione non è più in Form1 ma in una classe Program in un file program.cs, poco è cambiato.
Aprendo invece un applicazione Windows Forms con VB 2005, una delle poche certezze rimaste agli sviluppatori VB di lunga data, ovvero il fatto che, volendo, possiamo far partire la nostra applicazione da una Sub Main, sembra decaduta.
Aggiungendo la Sub Main questa non è più elencata nella combobox relativa allo startup object, perchè VB2005, by default, utilizza un nuovo concetto chiamato Application Framework, che è comunque deselezionabile nelle proprietà del progetto e, una volta disabilitato, farà riapparire nuovamente la vostra Sub Main e le vostre vecchie certezze.
L'Application Framework è un insieme di classi contenute nel namespace Microsoft.VisualBasic.ApplicationServices (in Microsoft.Visualbasic.dll) il cui scopo è quello di fornire un modello pratico e comune per le solite operazioni che interessano lo startup, shutdown e la vita di un applicazione windows forms.
L'idea è senza dubbio interessante, peccato che sotto certi punti di vista non sia stata implementata nel migliore dei modi (perlomeno fino a questa Beta2...).
La documentazione indica che grazie a questo modello è possibile gestire una serie di eventi abbastanza esplicativi quali:

  • Startup
  • Shutdown
  • SingleInstance
  • UnhadledException
  • NetworkAvailabilityChanged

Infatti cliccando su "View Application Events" nelle proprietà del progetto VB vi ritroverete una classe MyApplication (contenuta nel file ApplicationEvents.vb) e selezionado (MyApplication events) dalla solita combobox potete aggiungere gli handlers per gli eventi appena citati.
Se a questo punto, decidete di tornare alla vecchia Sub Main deselezionando l'opzione "Enable application framework" siete spacciati, il compilatore genera una serie di errori, spesso incomprensibili, legati alla classe generata dal designer e l'unica soluzione e quella di cancellare manualmente gli handlers avendo cura di non cancellare la definizione della classe stessa altrimenti la feature non è più abilitabile (vengono generati altri errori) a meno che non riallineate manualmente il contenuto del file ApplicationEvents.vb
All'interno degli event handlers è possibile scrivere qualcosa del tipo: MyBase.MainForm=... questo mi fa pensare che la classe MyApplication erediti da qualcos'altro e infatti, scrutando i vari files generati dal designer appare un file Application.Designer.vb all'interno del quale troviamo una parziale spiegazione alla nostra domanda.
La classe MyApplication in ApplicationEvents.vb è in realtà una classe parziale  (...e complimenti a chi ha deciso che in VB l'attributo Partial si possa, volendo, omettere...) e in Application.Designer.vb c'è la parte di classe che viene inizializzata dal designer sulla base delle selezioni impostate nelle proprietà del progetto alla voce Windows application framework properties.
Purtroppo, anche qui, nessuna traccia di Inherits, ma allora MyApplication da chi eredita?, la risposta sta su LadyBug ed è questa: "La classe MyApplication è in realtà composta da 3 classi, le due citate più una classe caricata in memoria per motivi di performances e mai salvata su file" la cui definizione è la seguente:

Partial Friend Class MyApplication : Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
End Class

...VB Magics is back...

Dalla quale si evince che la classe principale dell'application framework è la classe WindowsFormsApplicationBase la cui interfaccia è la seguente:

Come potete notare, la classe espone una serie di proprietà "tipiche" per un applicazione Windows Forms, quali IsSingleInstance, SplashScreen, EnableVisualStyles etc...
Analizzando meglio gli Application Events presenti in MyApplication e volendo inizializzare il form principale verrebbe spontaneo utilizzare qualcosa del tipo:

        Private Sub MyApplication_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
            MyBase.MainForm.Text = "Hello VB"
        End Sub

Peccato che MainForm venga valorizzato dopo l'evento e dopo tutti gli overrides disponibili dall'interno di MyApplication percui volendo accedere a MainForm dobbiamo necessariamente utilizzare My.Forms.(NomeForm) e tenere presente che il tutto funziona se, e solo se, il form principale ha espone un costruttore senza parametri, in caso contrario avrete degli errori di compilazione tutt'altro che "friendly".
Fortunatamente WindowsFormsApplicationBase non è sealed e malgrado erediti da ConsoleApplication(???) la quale a sua volta eredita da ApplicationBase possiamo crearci una classe ad-hoc per le nostre esigenze bypassando le limitazioni intrinsiche di Visual Studio 2005 a patto di scrivere qualche riga di codice.
Volendo, ad esempio, creare un applicazione SingleInstance, con i VisualStyles abilitati e relativo SplashScreen quello che dobbiamo scrivere è:

Imports Microsoft.VisualBasic.ApplicationServices

Public Class Program
    Private Shared WithEvents mApplication As WindowsFormsApplicationBase = New MyProgram()

    Public Shared Sub Main(ByVal args() As String)
        mApplication.Run(args)
    End Sub

    Public Shared ReadOnly Property Application() As WindowsFormsApplicationBase
        Get
            Return mApplication
        End Get
    End Property

    Public Class MyProgram
        Inherits WindowsFormsApplicationBase
        Public Sub New()
            MyBase.New()
            MyBase.MainForm = New Form1(0) 'funziona con un costruttore paramentrico
            MyBase.EnableVisualStyles = True
            MyBase.SplashScreen = New Splash() 'Splash screen
            MyBase.ShutdownStyle = ShutdownMode.AfterAllFormsClose
            MyBase.IsSingleInstance = True
        End Sub

        Private Sub MyProgram_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
            MessageBox.Show("Application is already running...")
        End Sub
    End Class

End Class

E volendo, possiamo sfruttare quanto messo a disposizione da WindowsFormsApplicationBase come la possibilità di accedere all' application log, al file AssemblyInfo, alle classi di ClickOnce e alla collezione OpenForms dei forms attualmente aperti semplicemente scrivendo Program.Application.XXX
Parlando di OpenForms val la pena segnalare che è comunque disponibile via Application.OpenForms e che quindi non è più una prerogativa di My e di VB 2005.
Il codice sopra segnalato è quindi, tutto l' application framework, è ovviamente utilizzabile anche da C# a patto che venga impostato un riferimento a Microsoft.VisualBasic.dll (sacrilegio! ) anche se in realta' molti si chiedono perche tutte le classi in Microsoft.VisualBasic.ApplicationServices non stiano all'interno di System.Windows.Forms.

Concludendo: Un aspetto interessante integrato in Visual Studio in un modo, a parer mio, "confuso e infelice", speriamo che che la RTM ci dia maggiori soddisfazioni.


PS: Avrei voluto verificare se l'evento UnhandledException intercetta le eccezioni generate in threads secondari ma la mia installazione di VB 2005 quando genera un eccezione in un thread secondario crasha miseramente...

Update: Sembra che il team stia fixando il problema generato quando si deseleziona il framework...