Newsgroup: it.comp.lang.visual-basic
Titolo: WaitForSingleObject (Era Problesa CreateProcess)

Vorrei sapere se qualcuno ha mai usato la CreateProcess con la 
WaitForSingleObject. 
Non mi e' molto chiaro l'uso di questa API ma l'ho vista spesso usare in 
concomitanza con la CreateProcess. A che serve? come funziona? La posso 
usare dopo aver chiamato la CreateProcess per attendere l'avvenuta 
esecuzione del processo? 
Grazie.
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~ KiavICQ:61810110 ~ KiavikHOO!:Kiavick ~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


  Dunque nel caso dell'uso con la CreateProcess serve ad attendere che il
processo sia effettimente terminato.
 Pui puň essere usato con dei Mutex ( in pratica variabili semaforiche ) per
sincronizzare 2 o piů processi.
Ciao
 
 
--------------------------------
Inviato via 
http://usenet.libero.it

 sincronizzare 2 o pi— processi.
e cioe'?


 > sincronizzare 2 o pi processi.
 
    Non è il tuo caso era solo per fare un esempio di utilizzo
Cmq ho passi alla WaitForSingleObject() un timeout ( secondo parametro ) di
tot secondi ( brutto ) oppure fai in FindWindow() finchè non ti trova la
finestra in questione ( meno brutto )
 Queste sono le prime due cose che mi sono venute in mente, se me ne viene in
mente una migliore te la faccio sapere.


 
Ok Grazie!


 Ok Grazie!
  Eccola l'idea :
  Const INFINITE = -1&
  Declare Function WaitForInputIdle Lib "user32" (ByVal hProcess As Long, _
                                                 ByVal dwMilliseconds As Long) As Long
 
  CreateProcess(..,..,.. )
  WaitForInputIdle(pID,INIFINTE ) '* Attende che l'applicazione sia pronta per
input
 ENJOY


 
Grazie la provo subito!
-- 
"Io so io e voi nun sete un cazzo!"
Albertone (R.I.P.)
ICQ:61810110 
YAHOO!:Kiavick

 
Ho implementato la tua idea, ho usato la CreateProcess ho chiamato la 
WaitForInputIdle e dopo ho chiamato l'EnumWindows per enumerare tutte le 
finestre (ho anche usato la funzione che mi hai passato prima ma non ha 
funzionato) ed ho notato che la finestra creata con la CreateProcess ha un 
PID DIVERSO da quello restituitomi nella ProcInfo!!!!!
Allora ho provato con la FindWindow ma non so perchè non funziona, gli 
passo pari pari il titolo della finestra ma no mi trova niente!
Idee?


 
A proposito di CreateProcess: Nel programmino C nel quale usavo la
CreateProcess per fare la stessa cosa quando valorizzavo la posizione e
la dimensione usavo la funzione strtoul che converte una stringa in un
unsigned long. I long del VB sono signed o unsigned? come faccio  per
creare un Unsigned Long? 


 Idee?
  Strano, il codice l'ho provato prima di postarlo ti scrivo come ho fatto:
Ret = CreateProcessA(...,..,...)
WaitForInputIdle ProcInfo.hProcess, INFINITE '* Qui passo l'handle al
processo non il PID
Ciao


 
Fin lě ci sono arrivato anche io, il problema č dopo quando devo cercare 
l'handle della finestra. Enumerando tutte le finestre con relativi PID 
non trovo corrispondenza con il pid passatomi dalla createprocess e 
quello trovato con la enumwindows...



  mmmm...strano a me funzia, o forse non ci capiamo, postami il pezzo di
codice che lo provo.
Ciaoo


 codice che lo provo.
Che sistema operativo hai? io ho win2k server


 Che sistema operativo hai? io ho win2k server
  WinXP Pro.
Ciao





Allora questo è il pezzo di codice che mi esegue la createprocess:
With StartInfo
   .cb = Len(StartInfo)
   .lpReserved = vbNullString
   .lpDesktop = vbNullString
   .lpTitle = vbNullString
   .dwFlags = STARTF_USESHOWWINDOW
  '.cbReserved2 = &H0
  '.lpReserved2 = &H0
  '.wShowWindow = SW_SHOW
End With
SecAttr1.nLength = Len(SecAttr1)
SecAttr2.nLength = Len(SecAttr1)
With StartInfo
   .dwFlags = STARTF_USESHOWWINDOW + STARTF_USEPOSITION + STARTF_USESIZE
   .dwX = AppModule.Xpos 'Questo è = a 0
   .dwY = AppModule.Ypos 'Questo a 0
   .dwXSize = AppModule.Width 'Questo a 200
   .dwYSize = AppModule.Height 'Questo a 200
   .wShowWindow = SW_SHOWDEFAULT
End With
Ret = CreateProcess(CommandLine, _
   AppModule.Param, _
   SecAttr1, _
   SecAttr2, _
   0, _
   NORMAL_PRIORITY_CLASS, _
   0, _
   AppModule.WorkingDir, _
   StartInfo, _
   ProcInfo)
CommandLine è = a C:\Winnt\Explorer.exe
Appmodule.param è = a /root,C:\backup
AppModule.WorkingDir è = a c:\Backup
Ora con il codice di sopra mi sta succedendo una cosa stranissima: la
createprocess ha successo ma non mi visualizza niente, controllando con il
taskmanager il processo viene creato ma muore immediatamente.
Se invece richiamo la createprocess impostando a null il secondo argomento
mi viene aperta una finestra di esplora risorse con l'albero delle cartelle,
che io non voglio...
Sto uscendo pazzo...


 AppModule.WorkingDir è = a c:\Backup
 Prova ad scrivere cosi
 CommandLine="C:\Winnt\Explorer.exe /root,C:\backup"
 Ret = CreateProcessA(vbNullString, _
                    CommandLine, _
                    sec1, _
                    sec2, _
                    False, _
                    0&, _
                    0&, _
                    vbNullString, _
                    StartInfo, _
                    ProcInfo)
 per quanto riguarda l'hWnd della finestra sto notando che la PID2Wnd non
funzia con esplora risorse!!! Mo cerco di capire
Ciao


 
Ci ho già provato ma non ha funzionato...



  Azz, a me funziona tranquillamente!!!! Cmq ora ho capito cosa intendevi che
la CreateProcess ti restituiva un PID diverso in effetti è cosi!!! Sto
cercando di capire perchè!
Intanto ti posto la dichiarazione delle strutture e della CreateProcess come
le ho fatte io conreontale con le tue, perchè a me funzia la
CreateProcess!!!
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
Private Type STARTUPINFO
   cb As Long
   lpReserved As String
   lpDesktop As String
   lpTitle As String
   dwX As Long
   dwY As Long
   dwXSize As Long
   dwYSize As Long
   dwXCountChars As Long
   dwYCountChars As Long
   dwFillAttribute As Long
   dwFlags As Long
   wShowWindow As Integer
   cbReserved2 As Integer
   lpReserved2 As Long
   hStdInput As Long
   hStdOutput As Long
   hStdError As Long
End Type
Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type
Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
  lpApplicationName As String, ByVal lpCommandLine As String, _
  lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As
SECURITY_ATTRIBUTES, _
  ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
  ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
  lpStartupInfo As STARTUPINFO, lpProcessInformation As _
  PROCESS_INFORMATION) As Long
Ed ora la parte di inizializzazione delle strutture e l'istruzione di
"lancio" :
With StartInfo
  .cb = Len(StartInfo)
  .lpReserved = vbNullString
  .lpDesktop = vbNullString
  .lpTitle = vbNullString
  .dwX = 0
  .dwY = 0
  .dwXSize = 320
  .dwYSize = 200
  .dwXCountChars = 0
  .dwYCountChars = 0
  .dwFillAttribute = 0
  .dwFlags = STARTF_USEPOSITION Or STARTF_USESIZE
  .wShowWindow = 0
  .cbReserved2 = 0
  .lpReserved2 = 0
  .hStdInput = 0
  .hStdOutput = 0
  .hStdError = 0
End With
c$ = "C:\Windows\Explorer.exe /root,C:\Inetpub"
sec1.nLength = Len(sec1)
sec2.nLength = Len(sec2)
Ret = CreateProcessA(vbNullString, _
                    c$, _
                    sec1, _
                    sec2, _
                    False, _
                    0&, _
                    0&, _
                    vbNullString, _
                    StartInfo, _
                    ProcInfo)
Intanto studio hehehehe
Ciaooo



Ok il codice che mi hai dato funziona ed ho anche scoperto perchè sto fijo
de na... non funzionava: era un problema di diachiarazione dell'api:
' NON funge Public Declare Function CreateProcess Lib "kernel32" Alias
"CreateProcessA"
' (ByVal lpApplicationName As String, _
' ByVal lpCommandLine As String,
' lpProcessAttributes As SECURITY_ATTRIBUTES,
' lpThreadAttributes As SECURITY_ATTRIBUTES,
' ByVal bInheritHandles As Long,
' ByVal dwCreationFlags As Long,
' lpEnvironment As Any,
' ByVal lpCurrentDriectory As String,
' lpStartupInfo As STARTUPINFO,
' lpProcessInformation As PROCESS_INFORMATION) As Long
Public Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA"
_
        (ByVal lpApplicationName As String, _
         ByVal lpCommandLine As String, _
         lpProcessAttributes As SECURITY_ATTRIBUTES, _
         lpThreadAttributes As SECURITY_ATTRIBUTES, _
         ByVal bInheritHandles As Long, _
         ByVal dwCreationFlags As Long, _
         ByVal lpEnvironment As Long, _
         ByVal lpCurrentDirectory As String, _
         lpStartupInfo As STARTUPINFO, _
         lpProcessInformation As PROCESS_INFORMATION) As Long
 
'NON funge Public Declare Function CreateProcess Lib "kernel32" Alias
"CreateProcessA"
' (ByVal lpApplicationName As String,
' ByVal lpCommandLine As String,
' lpProcessAttributes As Any,
' lpThreadAttributes As Any,
' ByVal bInheritHandles As Long,
' ByVal dwCreationFlags As Any,
' lpEnvironment As Any,
' ByVal lpCurrentDriectory As String,
' lpStartupInfo As STARTUPINFO,
' lpProcessInformation As PROCESS_INFORMATION) As Long
Quella non commentata è quella che mi hai passato tu le altre le ho trovate
in internet e come vedi alcuni parametri sono stati dichiarati come as Any
ed è quello secondo me che fa inputtanare l'api...
Rimane ancora il problema di scoprire perchè restituisce un PID diverso...
Secondo me quando lo esegui explorer controlla se per caso c'è già un'altra
istanza, passa il comando all'istanza esistente ed esce... Bastardo!
Grazie



  Già, credo anche io che sitratti di qualcosa del genere, anche perchè
explorer è sempre in esecuzione in pratica ( getisce la task bar e tutto il
resto ), tanto che che se non lanci nulla CMQ nei processi attivi c'è
explorer!!!
Probabilmente il trucco sta li, anche perchè con explorer falliscono sia la
WaitForSingleObject() sia la WaitForInputIdle() ( perchè giustamente
explorer è gia in esecuzione e pronto per lavorare...sto nfame eheheh ).
Ho riesumato allora un vecchio metodo ( si usava col VB 1.0 !!!! ) cioè
questo:
CreateProcess(...,..,...)
Do While FindWindow(vbNullString, <titolo finestra>) = 0
   DoEvents
Loop
Nel tuo caso tu lanci explorer cosi :
 "C:\Windows\Explorer.exe /root,C:\BackUp" ( mi pare !!! )
<titolo finestra> sarà : "BackUp" ( almeno su qui su XP è cosi verifica da
te... )
E' brutto ma questo funzia sicuro!!!!
A questo punto ti puoi risparmiare pure la CreateProcess() con tutto quel
"cinema" di parametri e strutture, ed usare la semplice Shell().
Per il momento credo che questa sia l'unica "pezza" per andare avanti.
Intanto continuo a studiare...
Ciaooo


 verifica da te... )
Dipende dalle impostazioni di explorer, se hai attivato l'opzione "mostra 
il percorso completo nella barra del titolo" allora sarà "C:\Backup"... è 
un gran casino comunque credo gli metterò sta pezza a colori
Grazie 
