Newsgroup: it.comp.lang.visual-basic
Titolo: Leggere dati da una finstra DOS

Avrei necessità di far leggere a un programma in VB l'output di un programma
che gira in una finestra DOS, ma davvero non so come fare.
Ho provato a fare una ricerca ma on ne sono venuto a capo. Non è che
qualcuno tra voi saprebbe essere così gentile da darmi una mano?
Grazie in anticipo.
Ale

Il 25/02/2004 14.55, Aleph scrisse:

Prova a spulciare qui:
http://groups.google.com/groups?hl=en&lr=&ie=ISO-8859-1&q=console&btnG=Google+Search&meta=group%3Dit.comp.lang.visual-basic
ciao
	maxx
-- 
NOSPAM: Rimuovere i trattini dallo username!
Cut hyphens from my username!

 maxx
Grazie Max, sei stato rapidoe  gentile, ma, dopo aver spulciato a dovere,
ho trovato solo un "mare magnum" di cose non sempre coerenti con la mia
richiesta o soluzioni estremamente complicate!
Non è che qualcuno ha già afforntato e risolto la questione?
Che so magari qualcuno sa se esite una classe già pronta o un controllo che
faccia il lavoro?
Si lo so che sto chiedendo il lavoro bell' e pronto, ma credo che non sia
molto saggio rifare con fatica quello che è già stato fatto.
Grazie cmq a tutti.
Ale

> Non è che qualcuno ha già afforntato e risolto la questione?
Io so che sotto MS-DOS per avere su file il risultato di un comando si fa:
Comando >file.txt
che ti redirige l'output su file invece che su schermo.
Ora non so su 2k/XP se va ancora... però quella potrebbe essere una 
soluzione...
-- 
Nella vita una sola cosa è certa: se la storia ci ha insegnato qualcosa, 
è che si può uccidere chiunque.
(Micheal Corleone)

 
Si', funziona ancora.


 Si', funziona ancora.
Siete gentilissimi, ma purtroppo nel mio caso on funge x due ragioni: 1)x
qualche ignoto motivo il programma in questione non reindirizza l'output su
file (il file.txt resta di 0 bytes!!); 2) ho necessitŕ di leggere l'output
in tempo reale durante l'elaborazione poiché sulla base di quello il
programma VB deve reagire con un proprio output.
Ne approfitto per fare un'altra domanda in parte correlata: che voi sappiate
č possibile aprire una finestra console in un form MDI??
Grazie
Ale
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 è possibile aprire una finestra console in un form MDI??
In linea di massima si', pero' non saprei spiegarti come fare. Devi 
leggerti il link che ti ho gia' dato. Altri metodi non li conosco.


"Aleph"
*.vbs
'questo e' uno spunto su come reindirizzare
'l'output e' c:\IniList.txt
'Far partire da start  esegui cscript INI.vbs  (invio)
wscript.stdout.writeline "start: " & now
set shell = createobject("wscript.shell")
set fso = createobject("scripting.filesystemobject")
sCmd = "%comspec% /c dir c:\*.ini /s > c:\IniList.txt"
shell.run sCmd,0,1
sText = fso.opentextfile("c:\IniList.txt").readall
wscript.stdout.writeline "finish: " & now
wscript.stdout.write sText
wscript.stdout.writeline ""
wscript.stdout.writeline ""
wscript.stdout.writeline "press ENTER to continue..."
wscript.stdin.readline
'Copia incolla su notepad e salva con estensione .vbs
'tutti i file (*.*)  poi ci clicchi sopra. (in questo esempio INI.vbs)
'se ti da' errore disattiva l'antivirus
--
Fosco

 ...
Ti ringrazio molto, ma, come dicevo poco sopra, a me non serve tanto
indirizzarlo in un file l'output quanto acquisirlo in tempo reale e getsirlo
da VB.
Mi spiego: l'applicazione dos chiamata effettua delle elaborazioni su grossi
file e fornisce in output alcuni dati che devono essere acquisiti dal mio
prog. Poi nel corso dell'eleborazione periodicamente segnala lo stato di
avanzamento (le dimensioni di un file) anche queste devono essere catturate
e gestite dal mio prog che, alla fine, deve accorgersi che ha finito (ma
questo lo so fare). Insomma il prog dos edeve girare nascosto e il mio prog
dovrebbe fare da GUI.

 ...
Peraltro non va. Disabilitato l'antivirus mi da l'errore:"handle non valido"

dovrebbe fare da GUI.
Le parole chiave in questo caso sono due funzioni dell'API:
CreateProcess e CreatePipe.
Ed e' cosi' che si approda a:
HOWTO: Create a Process for Reading and Writing to a Pipe
http://support.microsoft.com/support/kb/articles/Q173/0/85.ASP
-- 
ciao,
hal

Grazie dell'aiuto, ma ho provato a eseguire l'esempio che fanno
all'indirizzo che mi hai dato, ma non funziona mica sai?
Tu l'hai mai provato?
Ciao, Ale


Tu l'hai mai provato?
Ma scherzi davvero? Io l'avevo usato come base per un programma
sviluppato in un giorno e gira da almeno due anni ;-)
-- 
ciao,
hal

Scusami ma non so dove sbaglio l'ho copiato, creato il form, il pulsante la
listbox ma... mi da errore (createpocesso failed:3).
Sarà l'ora?
Ale


Sarà l'ora?
No, e' la cmdline sbagliata :-(
-- 
ciao,
hal

Sbagliata? In che senso? L'ho copiata paro paro....
HO provato anche un'altra routine simile trovata in un altro post e mi da un
problem simile (createprocess failed: 2).
MI aiuti per favore?
Grazie
Ale


MI aiuti per favore?
Mi sono pentito di averti detto che esistono le pipe - in inglese,
mica in francese :-P
Sai cosa vuol dire errore 2?
ERROR_FILE_NOTFOUND
Ed errore 3?
ERROR_PATH_NOT_FOUND
Studia, studia ;-)
-- 
ciao,
hal

Beh... è strano.. poichè esistono entrambi.... è la prima cosa che ho
controllato.. certo non sono un esperto e da studiare ho tanto.. ma è la
prima cosa che mi è venuta in mente...così il file l'ho messo in c:\ e ho
controllato la path... cmq ora riprovo vediamo se magari ho sbagliato a
trascrivere... ma è strano anche perché dopo l'errore il programma andava
anche in loop e dovevo chiderlo col task manager...
grazie comunque.
Ale



Ok sgamato dov'era l'errore la cosa va..ma fino a un certo punto... nel
senso che se l'output è su più linee il programma si pianta....
Comunque sei stato gentilissimo e ti sono grato per l'aiuto.
Ciao
ALe

alla fine per farlo funzionare ho dovuto modificarlo così!!!!
Option Explicit
      Private Declare Function CreatePipe Lib "kernel32" ( _
          phReadPipe As Long, _
          phWritePipe As Long, _
          lpPipeAttributes As Any, _
          ByVal nSize As Long) As Long
      Private Declare Function ReadFile Lib "kernel32" ( _
          ByVal hFile As Long, _
          ByVal lpBuffer As String, _
          ByVal nNumberOfBytesToRead As Long, _
          lpNumberOfBytesRead As Long, _
          ByVal lpOverlapped As Any) As Long
      Private Type SECURITY_ATTRIBUTES
          nLength As Long
          lpSecurityDescriptor As Long
          bInheritHandle As Long
      End Type
      Private Type STARTUPINFO
          cb As Long
         lpReserved As Long
         lpDesktop As Long
         lpTitle As Long
         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 PROCESS_INFORMATION
         hProcess As Long
         hThread As Long
         dwProcessID As Long
         dwThreadID As Long
         End Type
      Private Declare Function PeekNamedPipe Lib "kernel32" (ByVal
hNamedPipe As Long, lpBuffer As Any, ByVal nBufferSize As Long, lpBytesRead
As Long, lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long
      Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal
hProcess As Long, lpExitCode As Long) As Long
      Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
         lpApplicationName As Long, ByVal lpCommandLine As String, _
         lpProcessAttributes As Any, lpThreadAttributes As Any, _
         ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
         ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
         lpStartupInfo As Any, lpProcessInformation As Any) As Long
      Private Declare Function CloseHandle Lib "kernel32" (ByVal _
         hObject As Long) As Long
      Private Const NORMAL_PRIORITY_CLASS = &H20&
      Private Const STARTF_USESTDHANDLES = &H100&
      Private Const STILL_ACTIVE = &H103&
      Private hReadPipe As Long
      Private sPipedOutText As String
      Private iExit As Long
      Private fDone As Boolean
      Private Sub ExecCmd(cmdline$)
          Dim ret As Long, bSuccess As Long
          Dim proc As PROCESS_INFORMATION
          Dim start As STARTUPINFO
          Dim sa As SECURITY_ATTRIBUTES, hWritePipe _
          As Long
          Dim i As Integer
          iExit = -1
          sa.nLength = Len(sa)
          sa.bInheritHandle = 1&
          sa.lpSecurityDescriptor = 0&
          ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
          If ret = 0 Then
              MsgBox "CreatePipe failed. Error: " & Err.LastDllError
              Exit Sub
          End If
          start.cb = Len(start)
          start.dwFlags = STARTF_USESTDHANDLES
          start.hStdOutput = hWritePipe
          ' Start the shelled application:
          ret& = CreateProcessA(0&, cmdline$, sa, sa, 1&, _
          NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
          If ret <> 1 Then
              MsgBox "CreateProcess failed. Error: " & Err.LastDllError
              Exit Sub
          End If
          Do
              GetExitCodeProcess proc.hProcess, iExit
              DoEvents
          Loop Until ReadPipeChunk
          Text1 = sPipedOutText
          ret& = CloseHandle(proc.hProcess)
          ret& = CloseHandle(proc.hThread)
          ret& = CloseHandle(hReadPipe)
          ret& = CloseHandle(hWritePipe)
      End Sub
Function ReadPipeChunk(Optional sChunk As String, _
                       Optional ByVal cWant As Long = 512) As Boolean
    Dim f As Long, cGot As Long, cPeek As Long, fDone As Boolean, abChunk()
As Byte
    Dim sTemp As String
    ' See if program is done
    fDone = (iExit <> STILL_ACTIVE)
    ' See if there's more in the pipe
    f = PeekNamedPipe(hReadPipe, 0&, 0, 0, cPeek, 0)
    If (f <> 0) And (cPeek <> 0) Then
        ' Read a chunk of bytes
        sTemp = String(cWant, 0)
        Call ReadFile(hReadPipe, sTemp, cWant, cGot, 0&)
        sChunk = Left(sTemp, cGot)
        sPipedOutText = sPipedOutText & sChunk
    End If
    If (cPeek = 0) And fDone Then ReadPipeChunk = True
End Function
Private Sub Command1_Click()
  ExecCmd ("c:\winnt\system32\cmd.exe /c dir")
End Sub
ora fungeeeeeee
GRAZIEEEEE

senso che se l'output è su più linee il programma si pianta....
Quello di microsoft e' un esempio per farti capire cosa fare, poi e'
chiaro che il programma te lo scrivi tu come serve a te.
Io, quell'esempio li' l'avevo completamente stravolto, ma mi aveva
dato l'idea, che non pensavo si potesse fare anche in vb.
Ovviamente, se non hai chiaro cosa faccia e come funzioni l'API di
windows, vacci cauto, soprattutto se devi scrivere software per
clienti: a me spesso capita di testare programmi vb in cui e' stata
usata l'API a capocchia, con conseguente mia mail con lo stack delle
chiamate registrato dal dr. watson ;-)
-- 
ciao,
hal

GRAZIEEEEE
Grazie a te per l'impegno :-)
-- 
ciao,
hal

 
Lo stesso esempio (per win98) era nel link che ti avevo postato! ;-)
Tutto e' bene cio' che finisce bene.
ciao
	maxx
-- 
NOSPAM: Rimuovere i trattini dallo username!


 Peraltro non va. mi da l'errore:"handle non valido"
E' l'errore se lo fai partire con il click diretto sul file
far partire da start  esegui  (posizionato nella stessa cartella del VBS)
cscript INI.vbs
(invio)
Altrimenti  >>start esegui  FULLPATH\cscript INI.vbs  (invio)
Dove INI.vbs e il nome che hai dato al momento del salvataggio
news:it.comp.os.dos
http://www3.sympatico.ca/rhwatson/dos7/
(sintassi comandi dos)
--
Fosco

Sapete una cosa? dopo aver perso (e  fatto perdere) tanto tempo per riuscire
a capire come implementare il piping con le chiamate API ho scoperto che il
programma dos chiamato non lo supporta!!!!
Voglio dire che, detto test.exe il programma chiamato, così come non
funziona
test.exe > output.txt (che rimane di 0 bytes)
così non funziona il piping attraverso
...
ExecCmd (test.exe)
...
la text box rimane miseramente vuota.
Penso che abbandonerò il progetto anche se sonpo certo che si possa fare
perché qualcun altro ha sviluppato una GUI (molto carente e scarna però) per
lo stesso programma che funziona proprio come io avrei voluto.
Peccato.
Grazie a tutti per la vostra cortese diponibilità
Ciao
Ale

la text box rimane miseramente vuota.
Uhm... ma questo exe ha un output? E' a 16 o 32 bit?
Oltre a quanto esposto nell'esempio di msdn, c'e' un esempio che
potrebbe essere la soluzione al tuo problema qui:
http://www.codeproject.com/threads/redir.asp
E' in C++, ma usa comunque funzioni dell' API Win32 percio' adattabile
a visual basic.
-- 
hth, hal

 
Ma il programma test.exe come produce l'output? Le righe scritte 
scorrono verticalmente o il testo viene scritto in punti precisi della 
finestra dos (come se ci fossero delle "textbox")?


> così non funziona il piping attraverso


 Altrimenti  >>start esegui  FULLPATH\cscript INI.vbs  (invio)
OOOOPS
Altrimenti  >>start esegui  cscript FULLPATH\INI.vbs (invio)
--
Fosco