Newsgroup: it.comp.lang.visual-basic
Titolo: Open and Wait sul sito comune, sbagliato!

Salve a tutti.
Avevo esigenza di avviare un programma da shell e attendere che fosse
finito.
Così ho utilizzato il modulo OpenAndWait.bas che si trova sul sito comune.
Ebbene, non funziona.
Il fatto è questo: per uscire dal seguente Loop
        While oldExCode = ExCode
            GetExitCodeProcess ProcessHandle, ExCode
            DoEvents 'Consente di liberare risorse
        Wend
E' necessario che ad un certo punto ExCode sia diverso da oldExCode.
Da quanto si capisce dal programma questo dovrebbe avvenire quando si esce
dal programma eseguito in shell, invece ExCode è SEMPRE UGUALE A 0.
Ora mi chiedo... sono io che sbaglio qualche cosa o è il modulo che è fatto
male?
Non penso di sbagliare qualcosa perchè anche non apportando nessuna modifica
ed eseguendo il progetto cosi come si scarica dal sito, non funziona: ossia
apre il notepad.exe ma poi, quando lo si chiude, continua in quel ciclo
infinito senza mai interrompersi... che succede???
Riporto di seguito il codice intero per chi non lo conoscesse:
' ***************
' * OpenAndWait *
' ***************
'
' Adattamento di:
' Roberto Gismondi - 
ro...@iname.com
' (giugno 2000)
'
' Questo modulo è frutto dell'adattamento di codice pubblicato nel
' sito comune del newsgroup italiano "it.comp.lang.visual-basic" e
' fornisce la funzione "OpenAndWait" in alternativa
' alla funzione standard "Shell"; "OpenAndWait" consente di avviare
' un programma esterno in modo sincrono, ovvero attendendo la sua
' conclusione prima di proseguire con l'esecuzione del codice.
'
' A differenza della funzione "ShellWait" pubblicata nel sito comune,
' questa funzione consente di liberare risorse durante il ciclo di
' attesa e, soprattutto, incorpora inoltre un controllo (opzionale) del
' tempo di attesa, per garantire l'uscita dalla funzione.
'
' In caso di apertura e chiusura corrette del
' programma esterno la funzione restituisce il valore "0",
' in caso di superamento del "TempoLimite" (espresso in millisecondi)
' la funzione restituisce il valore "1", in caso di errore la funzione
' restituisce il valore "2".
' I valori restituiti possono ovviamente essere modificati a piacere.
'
' Esempio di utilizzo:
' --------------------
'    ........
'    Select case OpenAndWait(StringaComando, , 5000)
'        Case 0
'           MsgBox "Programma esterno finito !"
'        Case 1
'           MsgBox "E' stato superato il tempo limite di attesa !"
'        Case 2
'           MsgBox "Si è verificato un errore !"
'    End Select
'    ........
'
' Si ringraziano tutti i programmatori VB che partecipano attivamente
' al miglioramento dei contenuti del sito comune.
'
============================================================================
=================
Option Explicit
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 Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Function OpenAndWait(StringaComando As String, Optional StileFinestra
As Integer = vbNormalFocus, Optional TempoLimite As Long = 0) As Byte
    Const RitardoCiclo = 10        ' Ritardo di ciclo espresso in
millisecondi
    Dim TempoAttesa As Long
    Dim ProcessID As Long
    Dim ProcessHandle As Long
    Dim ExCode As Long
    Dim oldExCode As Long
    On Error GoTo GestioneErrore
    'Avvio il programma:
    ProcessID = Shell(StringaComando, StileFinestra)
    'Memorizzo l'handle del processo aperto:
    ProcessHandle = OpenProcess(1, 0, ProcessID)
    'Richiamo una prima volta la funzione di controllo per
    'avere il codice che identifica il programma mentre è attivo:
    GetExitCodeProcess ProcessHandle, ExCode
    oldExCode = ExCode
    'Verifico se il parametro opzionale "TempoLimite"
    'è stato passato alla funzione :
    If TempoLimite <> 0 Then
        'Attendo fino a quando l'ExCode non cambia, e quindi significa che
        'il programma sotto controllo è terminato;
        'contemporaneamente verifico anche il tempo di attesa:
        TempoAttesa = 0
        While oldExCode = ExCode
            GetExitCodeProcess ProcessHandle, ExCode
            Sleep RitardoCiclo
            TempoAttesa = TempoAttesa + RitardoCiclo
            If TempoAttesa >= TempoLimite Then
                ' La funzione termina e restituisce
                ' la segnalazione di tempo limite superato:
                OpenAndWait = 1
                Exit Function
            End If
            DoEvents 'Consente di liberare risorse
        Wend
        Else
        'Attendo fino a quando l'ExCode non cambia, e quindi significa che
        'il programma sotto controllo è terminato;
        'poichè non è stato passato il "TempoLimite",
        'non verifico il tempo di attesa:
        While oldExCode = ExCode
            GetExitCodeProcess ProcessHandle, ExCode
            DoEvents 'Consente di liberare risorse
        Wend
    End If
    ' La funzione restituisce la segnalazione di apertura
    ' e chiusura corrette del programma esterno:
    OpenAndWait = 0
    Exit Function
GestioneErrore:
    ' La funzione restituisce la segnalazione di errore
    OpenAndWait = 2
End Function
Lo riporto qui di seguito per chi non lo conoscesse:

         Wend
Non capisco il senso di questo loop in una funzione del genere.
Prova con la Shell Sospensiva (sempre sul SC) che usa la gestione classica
per questo problema (mi sembra di averla provata con successo tempo fa)
Ciao
--
' // Initialize the expression evaluator
Engines.Evaluator = CreateObject("
http://www.neodatatype.net
")
' // you can find resources for and from the NG here!
Me.SitoComune = "
http://www.it-lang-vb.net
"

 per questo problema (mi sembra di averla provata con successo tempo fa)
La mia shell è una chiamata ad un programma che gira sotto dos
In parole povere eseguo uno zip.exe per fargli zippare alcuni file presenti
nella cartella
Quindi quando lo zip termina, la finestra dos si chiude da sola.
Chi sa aiutarmi?
Ho provato con quello che dicevi tu, ma mi si blocca il computer!

Ho risolto il problema.
Ho usato la Shell Sospensiva ma non ho eseguito il programma zip sotto
finestra dos.
Ho creato un nuovo progetto e un nuovo exe che fa solo eseguire quello zip
sotto dos e poi termina.
In questo modo il programma principale aspetta che termini l'exe e non lo
zip sotto dos.
E cosě.. funziona.