Newsgroup: it.comp.lang.visual-basic
Titolo: Più istanze dell'applicazione ma stesso processo

Salve a tutti, ho creato con VB.Net 2010 una piccola applicazioncina che apre e visualizza dei file di formato proprietario. Adesso pensavo di poter far comunicare le eventuali istanze dell'applicazione in modo da avere ad esempio un'unica finestra delle impostazioni (come ad es. Internet Explorer) ma soprattutto per agevolare lo scambio dei dati tra varie istanze (copia/incolla dei dati utilizzando la stessa connessione al file di origine piuttosto che passare dalla clipboard di Windows).
I miei dubbi/problemi sono i seguenti:
 
1) Ne vale la pena o è meglio avviare le varie istanze come processi separati?
2) Non vorrei che in caso di crash di un'istanza questa blocchi l'intero processo assieme a tutte le altre istanze.
3) Non riesco a trovare sul web degli esempi per fare quello che voglio.
 
Grazie a tutti per qualsiasi suggerimento e/o rimando a link di interesse.

Rileggendo quanto ho scritto ho pensato che forse non sono stato molto chiaro.
 
In pratica dopo aver creato un'app che mi permette di aprire dei documenti dal formato ed estensione da me creati, e dopo aver registrato tale estensione nel registro di Windows in modo da poter aprire i documenti facendoci semplicemente doppio click sopra, quel che accade è che se apro più file in questo modo, Windows avvia giustamente il mio programma su più processi distinti.
 
Quello che vorrei ottenere è invece l'apertura di più file entro lo stesso processo, e per far questo pensavo a grandi linee di operare così:
 
1. All'avvio dell'applicazione controllo se esiste già un'istanza in esecuzione ed in caso positivo passo gli eventuali argomenti della riga di comando a tale istanza, terminando l'istanza corrente.
2. L'istanza già in esecuzione apre quindi l'eventuale file specificato in una nuova finestra eseguita in un nuovo thread.
 
Innanzitutto chiedevo se secondo voi l'idea è valida. E in caso positivo chiedevo gentilmente dove posso trovare esempi/tips sull'argomento. E' davvero strano che sul web non sia riuscito ancora a trovare niente di specifico sull'argomento ne in italiano ne in inglese, eppure mi pare che anche i programmi di Office tipo Word, Excel, ecc., facciano così, cioè aprono più documenti in distinte finestre ma sotto lo stesso processo, quindi l'idea non dovrebbe essere proprio assurda.

<<Word, Excel, ecc., facciano cosě, cioč aprono piů documenti in distinte 
finestre ma sotto lo stesso processo,
 
perchč sono programmi MDI 
 
 

 perchč sono programmi MDI
 
Non torna; non ci sono form padre e form figli come in una normale applicazione MDI. I vari documenti aperti (ad es. con Word 2010) hanno ognuno un pulsante distinto sulla barra di Windows ed infatti in gestione attività sono elencati come applicazioni distinte ma il processo è unico (WINWORD.EXE) almeno sul mio computer.


 
Gli esempi sono in C#, non credo sia troppo difficile
tradurli. Vedi se c'è qualcosa che funziona... ma prima
aspetta altre risposte :-).
 
Bye, G.


 
Gasp & Gulp, finalmente una traccia :-)

 Gasp & Gulp, finalmente una traccia :-)
 
Quello ti aiuta nella gestione delle form MDI ma dipende poi se davvero la tua applicazione fa quell'uso o meno delle finestre, che non è strettamente necessario per quello che vuoi fare.
 
Per quanto riguarda la richiesta iniziale, intercettare vari avvi della applicazione ma da una singola istanza, un mecccanismo piuttosto semplice e pulito è questo(facilmente convertible in VB):
http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
 
 
PostMessage ha il vantaggio che non devi conoscere l'handle della finestra della tua applicazione originaria, il messaggio viene trasmesso a tutte dal S.O., ma lo svantaggio è che non riesci a passare ulteriori dati al processo originario (per dire: la stringa con il nuovo nome di file aperto o quant'altro ti serve); se ne hai bisogno, devi usare un'altro sistema per far si che la seconda istanza, prima di chiudere, dia tutte le informazioni che servono alla prima... quindi socket/pipe/SendMessage/Remoting ecc..

> 
http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
 
 
Grazie della segnalazione. Ho trovato anche qualche altro link, ad occhio e croce c'è parecchio da studiare.

Nel caso possa interessare a qualcuno posto il metodo col quale dovrei aver risolto; dico dovrei perché il sistema non è ancora stato testato bene a modo, ma credo comunque che non ci debbano essere grosse sorprese.
 
- Innanzitutto nelle proprietà del progetto ho spuntato le voci "Attiva framework applicazione" e "Rendi ad istanza singola"
- Quindi ho creato una form dal nome StartupForm impostandola come form di avvio.
- Per tale form ho impostato la proprietà ShowInTaskbar su false e nell'evento Load ho inserito l'istruzione Me.Dispose (in pratica StartupForm serve solo all'istante dell'avvio dell'applicazione e poi sparisce per sempre).
- Il punto cruciale è invece la gestione degli eventi Startup e StartupNextInstance dell'applicazione (nelle proprietà del progetto fare click sul pulsante "Visualizza eventi applicazione"; verrà creato il file ApplicationEvents.vb dal quale è possibile appunto gestire questi eventi).
- Nella sub di gestione dell'evento Startup ho inserito il seguente codice che dovrebbe essere abbastanza autoesplicativo
 
Private Sub MyApplication_Startup(sender As Object, e As ApplicationServices.StartupEventArgs) Handles Me.Startup
    Dim T As Threading.Thread
    If e.CommandLine.Count = 0 Then
        T = New Threading.Thread(AddressOf NewThread)
        T.Start()
    Else
        For Each Arg As String In e.CommandLine
            T = New Threading.Thread(AddressOf NewThread)
            T.Start(Arg)
        Next
    End If
End Sub
 
dove la sub NewThread è qualcosa del genere
 
Friend Shared Sub NewThread(Arg As Object)
'Ogni chiamata a questa sub viene eseguita in un thread diverso.
    Dim FileToOpen As String = DirectCast(Arg, String)
    Dim MF As New MainForm
    MF.OpenFile(FileToOpen) 'OpenFile è un metodo che ho creato in MainForm...
    MF.ShowDialog()
End Sub
 
Il codice nella sub di gestione dell'evento StartupNextInstance è del tutto analogo.