Newsgroup: it.comp.lang.visual-basic
Titolo: Terminare applicazione Ms-Dos

Un saluto a tutto il NG.
Qualcuno potrebbe suggerirmi come far chiudere un programma ms-dos
precedentemente avviato con Shell?
Recuperando l'ID del processo, lo si potrebbe poi "uccidere"?
Ringrazio anticipatamente ogni possibile suggeritore.

 wrote in message
news:IxQ6f.4620$
65.1...@twister1.libero.it

Con WMI potresti fare cosě:
Dim obj As Object
For Each obj In GetObject("winmgmts:").ExecQuery("SELECT * FROM
Win32_Process WHERE Name='NomeFileDOZ.Estenzione'")
    Debug.Print "Name=" & obj.Name & " PID=" & obj.Handle
    obj.Terminate
Next
ALternativa API:
Se invece hai usato la Shell e ne hai l'Istanza del programma
puoi recuperarne l'Handle
Pid = Shell("c:\windows\ProgrammaDos.Estensione", vbNormalFocus)
If Pid = 0 Then MsgBox "Error starting the app"
mWnd = InstanceToWnd(Pid)
quindi ucciderlo:
    DestroyWindow mWnd
    TerminateProcess GetCurrentProcess, 0
Function InstanceToWnd(ByVal target_pid As Long) As Long
    Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
    'Find the first window
    test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
    Do While test_hwnd <> 0
        'Check if the window isn't a child
        If GetParent(test_hwnd) = 0 Then
            'Get the window's thread
            test_thread_id = GetWindowThreadProcessId(test_hwnd,
test_pid)
            If test_pid = target_pid Then
                InstanceToWnd = test_hwnd
                Exit Do
            End If
        End If
        'retrieve the next window
        test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
    Loop
End Function
Non ti elenco le dichiarazioni API ma credo siano esplicite...!
Se WMI non ti infastidisce lo ritengo meno complesso ed ugualmente
funzionale.
@ALex
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG


Solo un paio di osservazioni sul metodo alternativo:
"TerminateProcess GetCurrentProcess, 0" ha il simpatico effetto di uccidere il
processo corrente, non quello lanciato con shell...
Occorrerebbe ricavare l'handle con OpenProcess e passare quello alla
TerminateProcess.
    hProc = OpenProcess(PROCESS_ALL_ACCESS, False, ProcID)
    TerminateProcess hProc, 0
    CloseHandle hProc
E questo è più che sufficiente, non importa utilizzare DestroyWindow.
Bye
Raf

 Raf
Si hai ragione, nel codice che ho postato in realtà mancavano
dei pezzi, come quello di far diventare corrente il processo
prima di ucciderlo....!
Grazie dell'attenzione.
@Alex



Vi ringrazio delle risposte, ma non sono ancora in grado di cavarmela, le
mie conoscenze sono troppo scarse...WMI non sapevo nemmeno cosa fosse.
OpenProcess non riesco ad usarlo, mi chiede di definire la variabile
PROCESS_ALL_ACCESS, potrebbe essere dovuto al fatto che uso Win98 e VB6
(avevo letto fosse adatto per NT)?
Sia usando "TerminateProcess GetCurrentProcess", 0 oppure "ExitProcess mWnd"
mi si chiude VisualBasic mentre invece resta il programma avviato.
Tentero' ancora e sfruttero' google ulteriormente.
Vi ringrazio per l'attenzione e se riesco a combinare qualcosa di buono lo
postero'.
Saluti

 wrote in message
news:URb7f.6474$
65.2...@twister1.libero.it

Scusa se non sapevi cosa fosse WMI capisco,ma ti ho anche dato il codice
corretto per usarlo, usalo....!
Funziona con WinNT SP6
Saluti


 mi si chiude VisualBasic mentre invece resta il programma avviato.
Ma infatti mi ero accorto che quel codice conteneva qualche refuso ed avevo
postato una correzione, ma naturalmente mancavano tutte le definizioni delle
API e delle costanti (come PROCESS_ALL_ACCESS).
Ecco qui il codice completo:
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000&
Private Const SYNCHRONIZE As Long = &H100000
Private Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or
SYNCHRONIZE Or &HFFF)
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As
Long) As Long
Private Declare Function TerminateProcess Lib "kernel32.dll" (ByVal hProcess
As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal
dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As
Long) As Long
Public Sub KillProcess(ByVal ProcID As Long)
Dim hProc As Long
    hProc = OpenProcess(PROCESS_ALL_ACCESS, False, ProcID)
    TerminateProcess hProc, 0
    CloseHandle hProc
End Sub
Esempio:
ProcID=Shell(MyDosApp)
...
KillProcess ProcID
Bye
Raf

> > > [CUT]
Scopiazzando il codice che mi avete indicato funziona, vi ringrazio;
un'ultima curiosita':
PROCESS_ALL_ACCESS  non e' presente tra le voci "costanti" dell'Api Manager,
mentre le altre due sono presenti (STANDARD_RIGHTS_REQUIRED  e
SYNCHRONIZE ). Questo perche' devo aggiornare il file winapi oppure c'e'
un'altra ragione? mi sembra difficile poter tenere a mente tutte quelle
dichiarazioni....
ps: non mi era sfuggita la nota riguardo TerminateProcess e nei precedenti
tentativi avevo provato ad usare PutFocus e anche altre funzioni, ma
muoversi a casaccio non e' proprio indicato.
Grazie dell'attenzione

 dichiarazioni....
Ti consiglio di scaricarti ed installare APIViewer 2004, è molto più completo
dell'API manager fornito con VB.
http://www.activevb.de/rubriken/apiviewer/index-apiviewereng.html
Ciao
Raf


Ancora grazie, ciao