Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [vb.net] attendere che un processo termini

    Chiedo aiuto su questo problema:
    Ho un programma con una barra di menu, cliccando su una voce di menu viene aperto un processo esterno ("notepad.exe") che opera su un file di testo.
    Desidero che il programma chiamante rimanga in attesa che la finestra di notepad sia chiusa dall'utilizzatore.
    Il codice che ho trovato in rete sia con la richiesta WaitForExit sia con la creazione di un evento ad hoc per l'uscita dal programma sembra funzionare se notepad viene effettivamente chiuso, ma io vorrei che il programma chiamante non prosegua l'esecuzione anche quando notepad viene ridotto ad icona senza essere chiuso.
    Nel caso qualcuno per aiutarmi ha bisogno del codice, me lo comunichi e lo inserirò nel forum.
    Grazie.

  2. #2

    prova!

    Ciao io ho risolto con questo codice prova un pò e fammi sapere ciao ciao



    dichiarazioni da mettere in testa al modulo:
    Declare Function OpenProcess Lib “kernel32” _
    (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long
    Declare Function GetExitCodeProcess Lib “kernel32” _
    (ByVal hprocess As Long, lpExitCode As Long) As Long
    Declare Function CloseHandle Lib “kernel32” _
    (ByVal hObject As Long) As Long

    codice sorgente:
    Function RikShell(exe As String, Optional WinStyle) As Integer
    Dim processid As Long
    Dim hprocess As Long
    Dim exitcode As Long
    Dim parm As Integer

    ‘Controllo il parametro opzionale finestra
    Select Case VarType(WinStyle)
    Case vbEmpty, vbNull, vbError
    parm = vbNormalFocus
    Case vbLong, vbInteger, vbSingle, vbDouble
    parm = WinStyle
    Case Else
    parm = vbNormalFocus
    End Select
    ‘Prelevo l’ID del processo lanciato
    processid = Shell(exe, parm)
    ‘Creo un Handle per quel processo
    hprocess = OpenProcess(PROCESS_QUERY_INFORMATION, False, processid)

    Do
    ‘Controllo ripetutamente che termini
    Call GetExitCodeProcess(hprocess, exitcode)
    ‘Lascio libero il sistema di processare le altre
    ‘applicazioni
    DoEvents
    Loop While (exitcode = STILL_ACTIVE)
    CloseHandle (hprocess)

    End Function

    esempio:
    RikShell (“C:\Programmi\IBM\Client~1\rtopcb.exe e:\omega\bet\ancom.dtf”)

  3. #3
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    ta detto bene me lo sono ripassao proprio oggi il comando in vb.net

    proc = Process.Start(“Notepad.exe”)
    proc.WaitForInputIdle()

  4. #4
    Ringrazio per prima cosa quanti mi hanno risposto.
    Purtroppo le risposte ricevute non sono state in grado di darmi i suggerimenti necessari a risolvere il problema.
    Ho sperimentato solo la soluzione cassano, l'altra Luke(BI) l'ho solo letta in quanto opero in vb.net e la rutine sembra in vb6. Prima di cercare, se sono in grado, di portarla sotto .net gradirei sapere da Luke se lo scrivere Lascio libero il sistema di processare le altre applicazioni permette al programma chiamante di poter continuare ad operare copn altre opzioni di menù.
    Comunque a chiarimento del tutto posto il codice su cui sto lavorando

    Private Sub EDITA_FILE_CONFIGURAZIONE(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Menu2_2_01.Click, Menu2_2_02.Click, _
    Menu2_2_03.Click, Menu2_2_04.Click, _
    Menu2_2_05.Click, Menu2_2_06.Click, _
    Menu2_2_07.Click, Menu2_2_08.Click
    ' DESIDERATA
    ' la rutine richiama un programma esterno alla procedura scelto dall'utente (variabile globale gsEditorASCII) per editare i file
    ' di configurazione della procedura che sono dei file ASCII, posti nella cartella gsCartellaPIA : si desidera che l'utente
    ' una volta che abbia ha richiamato la presente opzione cliccando su una delle voci di menù sopra indicate
    ' non possa attivare altre opzioni dei menù della procedura stessa prima di chiudere e
    ' salvare il file di configurazione richiamato.
    ' La soluzione banale al problema, ma molto dispendiosa è quella di porre all'avvio di ogni opzione di menù
    ' la ricerca di istanze aperte dell' editorASCII e l'eventuale invito a chiuderle se operanti su file di configurazione.
    ' Si ricerca una soluzione meno dispendiosa.
    Dim NomeFileConfigurazione As String
    Select Case CType(sender, MenuItem).Text
    Case "Compensi Accessori" : NomeFileConfigurazione = "CAC.CFG"
    Case "Collaudo Amministrativo" : NomeFileConfigurazione = "COA.CFG"
    Case "Collaudo Statico" : NomeFileConfigurazione = "COS.CFG"
    Case "Prestazioni Ingegnere Capo" : NomeFileConfigurazione = "INC.CFG"
    Case "Prestazioni Geotecniche" : NomeFileConfigurazione = "GEO.CFG"
    Case "Prestazioni Informatiche" : NomeFileConfigurazione = "INF.CFG"
    Case "Numeri Indici Mensili ISTAT" : NomeFileConfigurazione = "IND.CFG"
    Case "Tasso Ufficiale di Sconto" : NomeFileConfigurazione = "TUS.CFG"
    End Select
    ' ==================n° 1 : soluzione mia iniziale =====
    Dim ShellProcess As New Process
    Try
    ShellProcess.StartInfo.FileName = gsEDITORASCII
    ShellProcess.StartInfo.UseShellExecute = True
    ShellProcess.StartInfo.Arguments = gsCartellaPia & NomeFileConfigurazione
    ShellProcess.Start()
    Catch ex As Exception
    Finally
    ShellProcess.Dispose()
    End Try
    ' RISCONTRO
    ' la soluzione non funziona in quanto se si minimizza la finestra dell'editorASCII è possibile proseguire
    ' con il programma attivando altre opzioni del menù principale
    ' ================== n° 2 : soluzione dotnet247 ==============
    '''''Dim ShellProcess As New Process
    '''''Try
    ''''' ShellProcess.StartInfo.FileName = gsEDITORASCII
    ''''' ShellProcess.StartInfo.UseShellExecute = True
    ''''' ShellProcess.StartInfo.Arguments = gsCartellaPia & NomeFileConfigurazione
    ''''' ShellProcess.Start()
    ''''' ShellProcess.WaitForExit()
    '''''Catch ex As Exception
    '''''Finally
    ''''' ShellProcess.Dispose()
    '''''End Try
    ' RISCONTRO
    ' la soluzione funziona ma presenta il grave inconveniente che dopo alcuni secondi lo sfondo del programma chiamante
    ' diviene bianco, solo la barra del titolo e la finestra di editorASCII rimangono visibili.
    ' Se si chiude la finestra di editorASCII tutto torna normale ed è possibile proseguire con il programma
    ' (la videata ritorna quella del programma) , ma se si minimizza la finestra dell'editorASCII e successivamente
    ' si clicca su un qualsiasi punto dello schermo appare sulla barra del titolo la scritta (Non Risponde).
    ' Riaprendendo la finestra dell'editorASCII minimizzata e chiudendo regolarmente editorASCII il programma riprende
    'regolarmente a funzionare.
    ' Si vorrebbe evitare l'inconveniente.
    ' ================== n° 3 : soluzione dotnet247 con suggerimento "cassano" ========
    '''''Dim ShellProcess As New Process
    '''''Try
    ''''' ShellProcess.StartInfo.FileName = gsEDITORASCII
    ''''' ShellProcess.StartInfo.UseShellExecute = True
    ''''' ShellProcess.StartInfo.Arguments = gsCartellaPia & NomeFileConfigurazione
    ''''' ShellProcess.Start()
    ''''' ShellProcess.WaitForInputIdle()
    '''''Catch ex As Exception
    '''''Finally
    ''''' ShellProcess.Dispose()
    '''''End Try
    ' RISCONTRO
    ' come soluzione n° 1
    ' ================== n° 4 : soluzione devx.com tip 18769 F. Balena ========
    ' La dichiarazione Private exited as boolean è fatta a livello di modulo
    ' la rutine process_Exited non fa altro che porre exited a true
    '''''Dim wordProc As Process = Process.Start(gsEDITORASCII, gsCartellaPia & NomeFileConfigurazione)
    '''''AddHandler wordProc.Exited, AddressOf Process_Exited
    '''''wordProc.EnableRaisingEvents = True
    '''''' do something else here
    '''''' (in this example just a loop that waits until the process exits
    '''''Do
    ''''' Threading.Thread.Sleep(1000)
    '''''Loop Until exited
    '''''RemoveHandler wordProc.Exited, AddressOf Process_Exited
    ' RISCONTRO
    ' come soluzione n° 2
    End Sub
    Grazie.

  5. #5

    eccomi...

    ti chiedo scusa ma non avevo letto VB.NET sono un pò un TONNO, in ogni caso lascia libero il sistema non l'applicazione chiamante

    ciao e scusa ancora

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Per comprendere meglio ...

    Non puoi disabilitare le voci di menu che ti interessano prima di eseguire il nuovo processo ed abilitarle alla fine ...?

  7. #7
    Rispondo ad oregon.

    La chiamata di un programma esterno è una esecuzione asincrona, ovvera il programma chiamante non aspetta la fine dell'esecuzione del programma esterno chiamato prima di proseguire.
    Da questo discende che ogni istruzione posta dopo la chiamata al programma esterno viene eseguita indipendentemente dalle vicissitudini di quest'ultimo.
    Per cui porre le istruzioni di abilitazioni delle voci dopo la chiamata, non serve dato tali istruzioni vengono eseguite comunque.
    Il fatto di porre la chiamata come ultima istruzione dell'evento click della voce di menù è un escamotage che permette di utilizzare il programma esterno fino a che non si richiama un'altra opzione di menù, visto che il programma si è riportato nello stato di attesa della scelta di una opzione fra quelli del main menu, e durante questa attesa l'utente può operare con il programma chiamato.
    Per fare quanto tu suggerisci occorre quindi intercettare l'evento di chiusura del programma esterno.
    Questo è possibile usando il metodo WaitForExit.
    Tale metodo costringe il programma chiamante ad attendere la fine del programma chiamato, prima di eseguire la successiva istruzione.
    Sfortunatamente durante tale attesa viene alterato il form da cui viene chiamato il programma esterno( scompare l'immagine di sfondo, che acquista il colore dello sfondo finestre scelto per windows, scompare il main menu, e l'utilizzatore ha la sgradevole sensazione che il programma non risponda più ai comandi).
    Invece chiudendo il programma chiamato, tutto ritorna normale.
    La soluzione del quesito potrebbe dunque limitarsi a trovare un qualche accorgimento che eviti la descritta alterazione del form durante l'attesa della chiusura del programma esterno.

    Grazie comunque.

  8. #8
    Utente di HTML.it
    Registrato dal
    Jul 2001
    Messaggi
    798
    è normale quel comporatamento, per fare in modo che non accada serve un ciclo di attesa con un DoEvents(). La soluzione numero 4 è quella che dovrebbe fare al caso tuo, prima della sleep aggiungi la DoEvents, dovrebbe funzionare.
    Ans.

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Grazie per la spiegazione ma credo di avere gia' idea dell'esecuzione asincrona, ecc ...

    Forse non mi sono spiegato bene ...

    Supponi di disabilitare i menu dell'applicazione, lanciare il programma esterno, attendere il termine del programma esterno con la WaitForExit *garantendo che il form principale non si blocchi*, riabilitare i menu ...

    Cosi' andrebbe bene?

  10. #10
    Rispondo a ans.
    Il suggerimento non sembra funzionare, è possibile eseguire altre opzioni dal menù del programma chiamante.

    Rispondo a oregon
    Ti chiedo scusa per averti tediato con informazioni da saccente.
    La soluzione che tu prospetti di disabilitare i menu è già eseguita automaticamente dall'istruzione WaitForExit, solo che il programma chiamante entra in stato di attesa disorientando l'utilizzatore al quale appare che il programma è incapace non solo di eseguire ulteriori istruzioni ma anche di ridisegnare il form chiamante.

    Reputo di aver trovato una soluzione, accettabile per gli scopi da me perseguiti e che metto a disposizione di quanti volessero utilizzarla.

    Prima di chiamare il programma esterno, visualizzo un form a tutto schermo, con disabilitati i pulsanti di gestione, contenente in alto una label che avverte l'utilizzatore che per proseguire occorre chiudere il programma esterno chiamato e con il colore di sfondo uguale al colore di sfonfo delle finestre di windows( quest'ultima accortezza fa si che non rimangano buchi nello sfondo se si minimizza la finestra del programma chiamato).
    Chiamo il programma esterno.
    Dò un refresh al form di avvertenza per dargli tempo e modo di visualizzare la label.
    Pongo l'istruzione WaitForExit.
    All'uscita il programma chiamante cancella il form di avvertenza e in modo automatica apparirà il form principale con i suoi menù.
    Il tutto sembra funzionare.
    Se qualcuno è interessato ad vederla funzionare e controllarla senza perdere tempo a scrivere il relativo codice, rendo noto che il codice è riportato nel progetto di prova ProgrammaEsterno scaricabile dal sito www.piasoft.it\esempi_net.htm..

    Saluto e ringrazio tutti, richiedo scusa a oregon.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.