Oppure

Loading
27/12/16 21:02
GN
Ma hai provato ad avviarlo tramite cmd.exe come ti dicevo prima? Comunque, questo
se elimino la parte del codice che genera il .bat , e lo creo manualmente l'applicazione riesce ad avviarlo

mi fa notare solo ora questa parte del codice che hai postato prima:
                For Indice As Short = 2 To ListaComandi.Items.Count + 2 
                    IO.File.AppendAllLines("C:\install.bat" & ListaComandi.Items(1).ToString, {ListaComandi.Items.Item(Indice)}) 
                Next 

Forse sono io che non capisco bene, oppure l'hai già corretta, ma mi sembra che ci sia qualcosa che non quadra.
Come puoi vedere qui msdn.microsoft.com/it-it/library/…(v=vs.110).aspx, il metodo AppendAllLines prende due argomenti. Il primo è il percorso del file su cui scrivere ed il secondo è una collezione di stringhe da scrivere sul file una per riga.
Perchè stai passando come primo argomento un nome di file concatenato al contenuto di un elemento di ListaComandi? Così facendo, se ad esempio l'elemento di indice 1 in ListaComandi è la stringa ciao, il file su cui andrai a scrivere sarà C:\install.batciao. Sicuro che è quello che volevi ottenere? Mi sembra alquanto strano, comunque se lo fosse dovresti tenerne conto quando vuoi avviare il file, cioè dovresti fare Process.Start("cmd.exe", "/C C:\install.bat" + ListaComandi.Items(1).ToString), e comunque non so se funzionerebbe dato che il file avrebbe un'estensione sconosciuta (tornando all'esempio, l'estensione batciao).

Inoltre, perchè stai usando quel metodo se scrivi una sola stringa alla volta (che inserisci in un'array di un singolo elemento usando le graffe per renderla una collezione)? Per scrivere una sola stringa c'è il metodo AppendAllText (vedi msdn.microsoft.com/it-it/library/…(v=vs.110).aspx).
Comunque, farlo in un ciclo non è ottimale perchè continui ad aprire il file e chiuderlo tante volte quante sono le linee da scrivere. Il metodo corretto e più efficiente (a mia conoscenza) è aprire il file prima del ciclo, scrivere sullo stream aperto nel ciclo, e poi chiudere il file (è questa l'operazione che rende definitiva la scrittura su disco) appena dopo il ciclo. Non mi ricordo quali sono classi/metodi del .net per farlo ma li trovi con una veloce ricerca.
Inoltre ho notato che come estremo superiore del ciclo usi ListaComandi.Items.Count + 2 , e all'interno del ciclo accedi agli Item usando l'indice del ciclo stesso (ListaComandi.Items.Item(Indice)). Se non sbaglio l'ultimo elemento della lista ha indice Items.Count-1, come è possibile che accedi agli altri dopo? Quel codice dovrebbe causare una IndexOutOfRangeException. E se per caso hai messo tutto il codice in un Try...Catch che prende tutte le eccezioni, probabilmente è uno dei motivi per cui non ti esegue il bat: il flusso di esecuzione esce dal try ed entra nel catch non appena il ciclo arriva al primo indice a cui non si può più accedere, e la chiamata al Process.Start, se è anch'essa nel blocco try, non verrà mai eseguita.
Ultima modifica effettuata da GN 27/12/16 21:05
aaa
27/12/16 21:25
Milo007
Postato originariamente da GN:

Ma hai provato ad avviarlo tramite cmd.exe come ti dicevo prima? Comunque, questo
se elimino la parte del codice che genera il .bat , e lo creo manualmente l'applicazione riesce ad avviarlo

mi fa notare solo ora questa parte del codice che hai postato prima:
                For Indice As Short = 2 To ListaComandi.Items.Count + 2 
                    IO.File.AppendAllLines("C:\install.bat" & ListaComandi.Items(1).ToString, {ListaComandi.Items.Item(Indice)}) 
                Next 

Forse sono io che non capisco bene, oppure l'hai già corretta, ma mi sembra che ci sia qualcosa che non quadra.
Come puoi vedere qui msdn.microsoft.com/it-it/library/…(v=vs.110).aspx, il metodo AppendAllLines prende due argomenti. Il primo è il percorso del file su cui scrivere ed il secondo è una collezione di stringhe da scrivere sul file una per riga.
Perchè stai passando come primo argomento un nome di file concatenato al contenuto di un elemento di ListaComandi? Così facendo, se ad esempio l'elemento di indice 1 in ListaComandi è la stringa ciao, il file su cui andrai a scrivere sarà C:\install.batciao. Sicuro che è quello che volevi ottenere? Mi sembra alquanto strano, comunque se lo fosse dovresti tenerne conto quando vuoi avviare il file, cioè dovresti fare Process.Start("cmd.exe", "/C C:\install.bat" + ListaComandi.Items(1).ToString), e comunque non so se funzionerebbe dato che il file avrebbe un'estensione sconosciuta (tornando all'esempio, l'estensione batciao).

Inoltre, perchè stai usando quel metodo se scrivi una sola stringa alla volta (che inserisci in un'array di un singolo elemento usando le graffe per renderla una collezione)? Per scrivere una sola stringa c'è il metodo AppendAllText (vedi msdn.microsoft.com/it-it/library/…(v=vs.110).aspx).
Comunque, farlo in un ciclo non è ottimale perchè continui ad aprire il file e chiuderlo tante volte quante sono le linee da scrivere. Il metodo corretto e più efficiente (a mia conoscenza) è aprire il file prima del ciclo, scrivere sullo stream aperto nel ciclo, e poi chiudere il file (è questa l'operazione che rende definitiva la scrittura su disco) appena dopo il ciclo. Non mi ricordo quali sono classi/metodi del .net per farlo ma li trovi con una veloce ricerca.
Inoltre ho notato che come estremo superiore del ciclo usi ListaComandi.Items.Count + 2 , e all'interno del ciclo accedi agli Item usando l'indice del ciclo stesso (ListaComandi.Items.Item(Indice)). Se non sbaglio l'ultimo elemento della lista ha indice Items.Count-1, come è possibile che accedi agli altri dopo? Quel codice dovrebbe causare una IndexOutOfRangeException. E se per caso hai messo tutto il codice in un Try...Catch che prende tutte le eccezioni, probabilmente è uno dei motivi per cui non ti esegue il bat: il flusso di esecuzione esce dal try ed entra nel catch non appena il ciclo arriva al primo indice a cui non si può più accedere, e la chiamata al Process.Start, se è anch'essa nel blocco try, non verrà mai eseguita.


grazie sono riuscito a risolvere :k:
aaa
27/12/16 22:42
Milo007
però resta un problema.. come posso capire quando il file .bat ha concluso , per poi poterlo eliminare ?
Ultima modifica effettuata da Milo007 27/12/16 22:42
aaa
28/12/16 14:43
GN
Una prima soluzione è bloccare l'esecuzione del programma finchè l'esecuzione termina. Invece che usare il metodo statico Process.Start, puoi associare al processo un'istanza della classe ProcessStartInfo, avviarlo tramite quella, e indicare al programma di fermarsi finchè il processo termina.
Esempio (non l'ho testato):
Dim p As New ProcessStartInfo("C:\install.bat")
p.UseShellExecute = True 'Usa la shell siccome devi eseguire uno script batch
p.Start() 'Avvia il bat
p.WaitForExit() 'Blocca il programma finchè il processo appena avviato non finisce
'il codice da qui in poi verrà eseguito solo dopo che l'esecuzione del .bat è terminata

Tuttavia, se stai scrivendo un'applicazione con una GUI (Windows Forms o WPF) ed esegui quel codice dal main thread, l'interfaccia rimarrà bloccata per tutto il tempo dell'esecuzione dello script batch. Se l'esecuzione è molto breve si può lasciare così (anche se, trattandosi di una GUI, a mio avviso non è comunque una soluzione molto "pulita";); per fare le cose per bene evitando che l'interfaccia si blocchi, si può:
- Eseguire il tutto su un thread separato (vedi la classe Thread)
- Utilizzare la classe Process e gestirne l'evento Exited; le istruzioni nel gestore di quell'evento verranno eseguite una volta che il processo è terminato (qui msdn.microsoft.com/it-it/library/…(v=vs.110).aspx documentazione ed esempi).
Ultima modifica effettuata da GN 28/12/16 14:44
aaa
28/12/16 15:13
Milo007
L'esecuzione del .bat è molto veloce quindi non sarebbe un problema.. appena torno a casa provo se funziona e vi faccio sapere
aaa
28/12/16 23:09
Milo007
non va , mi compaiono questi errori :

Errore    BC30456    'Start' non è un membro di 'ProcessStartInfo'.
Errore    BC30456    'WaitForExit' non è un membro di 'ProcessStartInfo'.    
aaa
29/12/16 15:27
GN
Ok scusami ho sbagliato, Start e WaitForExit sono metodi della classe Process e non ProcessStartInfo. Un'istanza di Process viene ritornata dalla chiamata al metodo statico Start di Process stessa, quindi così dovrebbe funzionare:
Process.Start("cmd.exe", "/C C:\install.bat").WaitForExit()
aaa
30/12/16 1:33
Milo007
Solo che così non posso nascondere il terminale con la funzione ProcessWindowStyle.Hidden...
Oppure c'è un sistema per poterlo fare ugualmente?


Ultima modifica effettuata da Milo007 30/12/16 8:06
aaa