[VB6] output van DOS prog in VB

Pagina: 1
Acties:

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Ik ben dus een GUI over het programma LDIFDE.EXE (AD Tool) aan het maken, nou genereerd die LDIFDE.EXE (een DOS programma) een output, ik wil deze weergeven in het log van mijn VB Programma...

Ook genereerd die ldifde.exe een log in txt formaat, is er een mogelijkheid om dmv een timer ofzo te checken wanneer die txt file veranderd en het dan weer te geven in een weer ander log van mijn VB Programma?

Waar moet ik aan gaan denken, of wat voor keywords kan ik gebruiken om te gaan zoeken?

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Op dinsdag 16 juli 2002 10:55 schreef Praeth het volgende:
Ik ben dus een GUI over het programma LDIFDE.EXE (AD Tool) aan het maken, nou genereerd die LDIFDE.EXE (een DOS programma) een output, ik wil deze weergeven in het log van mijn VB Programma...
[mierenneukmode]
genereerT .... :)
[/mierenneukmode]

kun je niet proberen bij het oproepen van dat programma
c:\>LDIFDE.EXE > output.txt

en dan dat .txt filetje inladen in een rtf-textbox in VB
Ook genereerd die ldifde.exe een log in txt formaat, is er een mogelijkheid om dmv een timer ofzo te checken wanneer die txt file veranderd en het dan weer te geven in een weer ander log van mijn VB Programma?
Mbv een timer kun je de datum/tijd van het logbestand controleren.

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Okay, ik heb het nu zo gekregen dat ik de output van ldifde.exe in log.txt heb staan...

Ik heb een rich textbox op m'n form staan, die is realtime, en geeft alles weer wat er gebeurd, maar je raad natuurlijk al wat er gebeurd als ik dit doe:
code:
1
rtbLog.text = rtbLog.text & (monitor log.txt)*

* weet nog niet hoe dat moet.

Dan zal ik in mijn rtbLog.text heel de tijd dezelfde log.txt entries krijgen... niet de bedoeling.

Begrijpen jullie wat ik bedoel?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 03-04 17:10

Janoz

Moderator Devschuur®

!litemod

Is het met VB niet mogelijk om de standard input en output op te vangen van aangeroepen commando's?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Ben ik op dit moment mee bezig, maar we gaan nu eerst ff eten met de afdeling ;)

I'll let ya know

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Okay, ik heb een module gevonden... dmv van bovenstaande link.

Maar nu? |:( De module het MGetCmdOutput

Hoe moet ik nu de output van de file ldifde.exe in m'n Rich Text Box krijgen?

Zie module:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
Option Explicit

'''''''''''''''''''''
'''   Constants   '''
'''''''''''''''''''''

' STARTUPINFO flags
Private Const STARTF_USESHOWWINDOW = &H1
Private Const STARTF_USESTDHANDLES = &H100

' ShowWindow flags
Private Const SW_HIDE = 0

' DuplicateHandle flags
Private Const DUPLICATE_CLOSE_SOURCE = &H1
Private Const DUPLICATE_SAME_ACCESS = &H2

' Error codes
Private Const ERROR_BROKEN_PIPE = 109


'''''''''''''''''
'''   Types   '''
'''''''''''''''''

Private Type SECURITY_ATTRIBUTES
  nLength As Long
  lpSecurityDescriptor As Long
  bInheritHandle 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 PROCESS_INFORMATION
  hProcess As Long
  hThread As Long
  dwProcessId As Long
  dwThreadId As Long
End Type


''''''''''''''''''''
'''   Declares   '''
''''''''''''''''''''

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, _
  lpBuffer As Any, _
  ByVal nNumberOfBytesToRead As Long, _
  lpNumberOfBytesRead As Long, _
  lpOverlapped As Any) As Long

Private 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 Long, _
  lpEnvironment As Any, _
  ByVal lpCurrentDriectory As String, _
  lpStartupInfo As STARTUPINFO, _
  lpProcessInformation As PROCESS_INFORMATION) As Long

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

Private Declare Function DuplicateHandle Lib "kernel32" ( _
  ByVal hSourceProcessHandle As Long, _
  ByVal hSourceHandle As Long, _
  ByVal hTargetProcessHandle As Long, _
  lpTargetHandle As Long, _
  ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, _
  ByVal dwOptions As Long) As Long

Private Declare Function CloseHandle Lib "kernel32" ( _
  ByVal hObject As Long) As Long

Private Declare Function OemToCharBuff Lib "user32" Alias "OemToCharBuffA" ( _
  lpszSrc As Any, _
  ByVal lpszDst As String, _
  ByVal cchDstLength As Long) As Long


''''''''''''''''''''''''''
'''   Public methods   '''
''''''''''''''''''''''''''

'
' Function GetCommandOutput
'
' sCommandLine:  [in] Command line to launch
' fStdOut     [in,opt] True (defualt) to capture output to STDOUT
' fStdErr     [in,opt] True to capture output to STDERR. False is default.
' fOEMConvert:   [in,opt] True (default) to convert DOS characters to Windows, False to skip conversion
'
' Returns:   String with STDOUT and/or STDERR output
'
Public Function GetCommandOutput(sCommandLine As String, Optional fStdOut As Boolean = True, _
                       Optional fStdErr As Boolean = False, Optional fOEMConvert As Boolean = True) As String

  Dim hPipeRead As Long, hPipeWrite1 As Long, hPipeWrite2 As Long
  Dim hCurProcess As Long
  Dim sa As SECURITY_ATTRIBUTES
  Dim si As STARTUPINFO
  Dim pi As PROCESS_INFORMATION
  Dim baOutput() As Byte
  Dim sNewOutput As String
  Dim lBytesRead As Long
  Dim fTwoHandles As Boolean
  
  Dim lRet As Long
  
  
  Const BUFSIZE = 1024  ' pipe buffer size
  
  ' At least one of them should be True, otherwise there's no point in calling the function
  If (Not fStdOut) And (Not fStdErr) Then Err.Raise 5      ' Invalid Procedure call or Argument
  
  ' If both are true, we need two write handles. If not, one is enough.
  fTwoHandles = fStdOut And fStdErr
  
  ReDim baOutput(BUFSIZE - 1) As Byte

  With sa
    .nLength = Len(sa)
    .bInheritHandle = 1    ' get inheritable pipe handles
  End With
  
  If CreatePipe(hPipeRead, hPipeWrite1, sa, BUFSIZE) = 0 Then Exit Function
  
  hCurProcess = GetCurrentProcess()
  
  ' Replace our inheritable read handle with an non-inheritable. Not that it
  ' seems to be necessary in this case, but the docs say we should.
  Call DuplicateHandle(hCurProcess, hPipeRead, hCurProcess, hPipeRead, 0&, _
                 0&, DUPLICATE_SAME_ACCESS Or DUPLICATE_CLOSE_SOURCE)
  
  ' If both STDOUT and STDERR should be redirected, get an extra handle.
  If fTwoHandles Then
    Call DuplicateHandle(hCurProcess, hPipeWrite1, hCurProcess, hPipeWrite2, 0&, _
                 1&, DUPLICATE_SAME_ACCESS)
  End If
  
  With si
    .cb = Len(si)
    .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
    .wShowWindow = SW_HIDE      ' hide the window
    
    If fTwoHandles Then
    .hStdOutput = hPipeWrite1
    .hStdError = hPipeWrite2
    ElseIf fStdOut Then
    .hStdOutput = hPipeWrite1
    Else
    .hStdError = hPipeWrite1
    End If
  End With
    
  If CreateProcess(vbNullString, sCommandLine, ByVal 0&, ByVal 0&, 1, 0&, _
             ByVal 0&, vbNullString, si, pi) Then
    
    ' Close thread handle - we don't need it
    Call CloseHandle(pi.hThread)
    
    ' Also close our handle(s) to the write end of the pipe. This is important, since
    ' ReadFile will *not* return until all write handles are closed or the buffer is full.
    Call CloseHandle(hPipeWrite1)
    hPipeWrite1 = 0
    If hPipeWrite2 Then
    Call CloseHandle(hPipeWrite2)
    hPipeWrite2 = 0
    End If

    Do
    ' Add a DoEvents to allow more data to be written to the buffer for each call.
    ' This results in fewer, larger chunks to be read.
    'DoEvents
    
    If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then Exit Do
    
    If fOEMConvert Then
      ' convert from "DOS" to "Windows" characters
      sNewOutput = String$(lBytesRead, 0)
      Call OemToCharBuff(baOutput(0), sNewOutput, lBytesRead)
    Else
      ' perform no conversion (except to Unicode)
      sNewOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
    End If
    
    GetCommandOutput = GetCommandOutput & sNewOutput
    
    ' If you are executing an application that outputs data during a long time,
    ' and don't want to lock up your application, it might be a better idea to
    ' wrap this code in a class module in an ActiveX EXE and execute it asynchronously.
    ' Then you can raise an event here each time more data is available.
    'RaiseEvent OutputAvailabele(sNewOutput)
    Loop
    
    ' When the process terminates successfully, Err.LastDllError will be
    ' ERROR_BROKEN_PIPE (109). Other values indicates an error.
    
    Call CloseHandle(pi.hProcess)
    
  End If
  
  ' clean up
  Call CloseHandle(hPipeRead)
  If hPipeWrite1 Then Call CloseHandle(hPipeWrite1)
  If hPipeWrite2 Then Call CloseHandle(hPipeWrite2)
  
End Function

Verwijderd

Lees je eigen post nou es op je gemak door...er staat precies in hoe het werkt... L E Z E N

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Op dinsdag 16 juli 2002 14:17 schreef Yarvieh het volgende:
Lees je eigen post nou es op je gemak door...er staat precies in hoe het werkt... L E Z E N
Nou je het zegt ja ;)


Gooi deze thread maar op slot.

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Okay! M'n raam staat al open! :(

Ik heb er nou 2 uurtjes mee bezig, met die module die ik hier ook gepost heb, is er iemand die mij kan vertellen hoe hij werkt als je hem zo ziet?

Boehoehoehoheoe ;(

Ik wil alleen maar ldifde.exe uitvoeren en daarvan de output in rtblog.text laten weergeven |:(

Is moeilijker dan ik dacht! Is er een VB Goeroe hier aanwezig?

Verwijderd

Laat eens je code tot nu toe zien?

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Op dinsdag 16 juli 2002 16:11 schreef MrX het volgende:
Laat eens je code tot nu toe zien?
Dat maakt niet echt veel uit, de code die ik nu heb is alleen maar rotzooi, en niet van toepassing op wat ik wil...

Kijk, zal het ff uitleggen, ik wil dmv 1 button een dos programma uitvoeren, genaamd ldifde.exe, ik heb een module (zie eerdere post) gevonden die de output van een programma kan capturen, nu staat er in die module:
code:
1
2
3
4
5
6
7
8
9
10
11
' Function GetCommandOutput
'
' sCommandLine:  [in] Command line to launch
' fStdOut     [in,opt] True (defualt) to capture output to STDOUT
' fStdErr     [in,opt] True to capture output to STDERR. False is default.
' fOEMConvert:   [in,opt] True (default) to convert DOS characters to Windows, False to skip conversion
'
' Returns:   String with STDOUT and/or STDERR output
'
Public Function GetCommandOutput(sCommandLine As String, Optional fStdOut As Boolean = True, _
                       Optional fStdErr As Boolean = False, Optional fOEMConvert As Boolean = True) As String

Dus ik dacht, ik zet onder die button.
code:
1
GetCommandOutput (ldifde.exe,true,false,false)

Of iets dergelijks, maar ja, twil niet echt werken...
Want die output moet toch ook ergens in een string komen te staan ofzo, die ik later weer kan gebruiken om in die rich textbox te laten verschijnen..

Ik snap er de ballen ff niet van |:(

Verwijderd

code:
1
strText=GetCommandOutput (ldifde.exe,true,false,false)

  • JoMr3
  • Registratie: November 2001
  • Laatst online: 19-09-2025
Die functie levert een string op. Die moet je gewoon toekennen aan een variabele of aan die tekstbox. Dus bijvoorbeeld:
code:
1
2
3
Dim log As String

log = GetCommandOutput (ldifde.exe,true,false,false)

of
code:
1
rtftextbox.Text = GetCommandOutput (ldifde.exe,true,false,false)

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Op dinsdag 16 juli 2002 16:20 schreef Sepans het volgende:
code:
1
strText=GetCommandOutput (ldifde.exe,true,false,false)
Dat d8 ik nou ook, maar dan krijg ik een 'object required' error met heel die betreffende regel geel, no way dat ik iets mis, want alles is aanwezig!

Snappen jullie nou dat ik gek wordt? |:( :+

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Op dinsdag 16 juli 2002 16:25 schreef JoMr3 het volgende:
Die functie levert een string op. Die moet je gewoon toekennen aan een variabele of aan die tekstbox. Dus bijvoorbeeld:
code:
1
2
3
Dim log As String

log = GetCommandOutput (ldifde.exe,true,false,false)

of
code:
1
rtftextbox.Text = GetCommandOutput (ldifde.exe,true,false,false)
Levert het zelfde op, 'object required'

  • DaRace
  • Registratie: Juni 2001
  • Laatst online: 03-10-2023
wat dacht je van de commandstring tussen quotes zetten? nu denkt hij dat het een object is....

Dus:
log = GetCommandOutput ("ldifde.exe",true,false,false)

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Op dinsdag 16 juli 2002 16:32 schreef DaRace het volgende:
wat dacht je van de commandstring tussen quotes zetten? nu denkt hij dat het een object is....

Dus:
log = GetCommandOutput ("ldifde.exe",true,false,false)
Als je een meisje was geweest had ik je gezoend! *D




Case closed.

  • JoMr3
  • Registratie: November 2001
  • Laatst online: 19-09-2025
Klassiek geval van "type mismatch" :P

Verwijderd

Klassiek geval van compleet clueless, maak eerst es gewoon wat simpele programmatjes zodat je weet wat je aan het doen bent (wat ervaring opdoen met de taal), want 't komt nu over alsof je gewoon eindeloos syntax zit te proberen tot er iets werkt.

  • Praetorian
  • Registratie: November 2001
  • Laatst online: 21-03 15:23
Tuuuuurlijk Yarvieh :{
-


Oke, het werkt nu bijna vlekkeloos, het laat alleen m'n programma hangen, nu heb ik gelezen dat dit voorkomen kan worden door de code (die je hierboven ziet) in een Class module te frutselen, dat heb ik gedaan.

Dan moet ik asynchroon gaan updaten..., iemand ervaring? :)

Dit staat er precies:
If you are executing an application that outputs data during a long time, and don't want to lock up your application, it might be a better idea to wrap this code in a class module in an ActiveX EXE and execute it asynchronously.
Then you can raise an event here each time more data is available.
RaiseEvent OutputAvailabele(sNewOutput)
Er staat dus ook dat ik een ActiveX EXE moet maken, moet ik daar de rest van m'n forms in maken dan? of is er geen verschil, want ik heb nu al heel m'n project in een standard EXE gemaakt. Of moet ik alles echt over gaan planten.
Pagina: 1