|
That's the whole codes when "Run" is clicked.
Yes, I need to waiting for the process to exit, I need to get the return string and display them in the form. That's why I use
p.WaitForExit(5400000). But use p.WaitForExit(5400000) will hang progressbar form, if don;t use p.WaitForExit(5400000), when should I close the progressbar form?
Private Sub OnProcesited(ByVal sender As Object, ByVal e As System.EventArgs)
Dim p As System.Diagnostics.Process
p = sender
Dim rtnStr As String = String.Empty
rtnStr = p.StandardOutput.ReadToEnd()
If rtnStr.Contains(" FAST terminated normally.") = True Then
rtnStr = rtnStr & vbCrLf & "Please click Postprocess -> View Output File in menu to view the file."
updateViewMenu()
End If
'''progBarFrm.Close()
'''progBarFrm.Dispose()
Dim frm As New FormShowFASTResult
frm.txtFASTResult.Text = rtnStr
frm.Button1.Select()
frm.ShowDialog()
End Sub
|
|
|
|
|
You still have absolutely nothing updating the progress bar. You called Show on the form to show the form with the progress bar on it, but you've got nothing at all that updates the progress bar, so it's not going to do anything.
Without seeing the code behind the progressbar form, this is about all we can say.
|
|
|
|
|
Progressbar value should be updated using timer inside the form, after call SHOW of the form, the timer will be started, sure you cannot see these codes from inside the function which create the form.
|
|
|
|
|
I found only if I clearly call p.Kill(), the Exited event will be triggered, but when I should call the .Kill() for a process?
if I use p.WaitForExit(5400000), the program will be hanged to wait for process to exit, the progressbar form will be hanged.
|
|
|
|
|
The process will drop by itself. You shouldn't have to call Kill on it at all. Once the process you launched quits on its own, the Exited event will be raised.
5400000?? Really? 90 minutes??
You do realize WaitForExit is a blocking call, right? No other code will execute so long as WaitForExit is waiting. Remove this line and just let it run. When the target app is finished, your event handler will get called.
|
|
|
|
|
Sorry calculation error, I already comment out that line. Now I modify the source codes, also remove the event.
When "Run" menu is clicked, it will call Run_Tool() inside which it start a precess and open a form, I also show the codes for progressbar form below, but the progressbar color is grayed, no value is shown.
Would you please take a look where is wrong? thanks!
Private Sub Run_Tool()
Dim sAppPath As String = ".\xxxx.exe"
Dim fileName As String = "XXXXXX.TXT"
Dim p As New System.Diagnostics.Process()
Dim rtnStr As String = String.Empty
p.StartInfo.FileName = Application.StartupPath & "\" & sAppPath
p.StartInfo.Arguments = fileName
'Do not use the system shell to start the program this is so we can hide the command dos window
p.StartInfo.UseShellExecute = False
p.StartInfo.WorkingDirectory = strOutputFilePath
' Show no dos window if false
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardOutput = True
Dim progBarFrm As New FormProgressBar
progBarFrm.Show()
Try
p.Start()
Catch ex As Exception
ShowValidationMessage("Unexception error is caught, please close and try again.", "Error")
'p.Kill()
progBarFrm.Close()
Return
End Try
rtnStr = p.StandardOutput.ReadToEnd()
''p.WaitForExit(120000) '= 1.5 min: 1000 millisecond = 1 second
' if the process doesn't complete within 5400 seconds, kill it
''If Not p.HasExited Then
''p.Kill()
''End If
If rtnStr.Contains(" FAST terminated normally.") = True Then
rtnStr = rtnStr & vbCrLf & "Please click Postprocess -> View Output File in menu to view the file."
updateViewMenu()
End If
progBarFrm.Close()
Dim frm As New FormShowFASTResult
frm.txtFASTResult.Text = rtnStr
frm.Button1.Select()
frm.ShowDialog()
End Sub
Source code for the progressbar form as the following
Public Class FormProgressBar
Private Sub FormProgressBar_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
Timer1.Stop()
End Sub
Private Sub FormProgressBar_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.CenterToScreen()
ProgressBar1.Minimum = 0
ProgressBar1.Maximum = 100
ProgressBar1.Value = 0
Timer1.Interval = 1
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If ProgressBar1.Value < 100 Then
ProgressBar1.Value = ProgressBar1.Value + 1
Else
ProgressBar1.Value = 0
End If
End Sub
End Class
|
|
|
|
|
First, ReadToEnd isn't going to give you what you're looking for. It'll block until the console has to something to return, and even then, it'll return block of text, most likely NOT all of the text your app output to the console, and it will only read ONE block of text.
Now, if you want to gather all the text the app outputs, and still have a responsive UI (such as the progress bar redrawing itself), you'll have to read the console output asynchronously.
Something like:
Private Sub StartConsoleRead(ByRef st As Stream)
Dim rdo As New ReadData
'rdo.s = _conStream.BaseStream
rdo.s = st
Dim consoleReadAsyncCallback As New AsyncCallback(AddressOf ConsoleReadCallback)
_conStream.BaseStream.BeginRead(rdo.buffer, 0, rdo.buffer.Length, consoleReadAsyncCallback, rdo)
End Sub
Private Sub ConsoleReadCallback(ByVal asyncResult As IAsyncResult)
Dim rdo As ReadData = DirectCast(asyncResult.AsyncState, ReadData)
Dim bytesRead As Integer = rdo.s.EndRead(asyncResult)
Dim enc As Encoding = Encoding.ASCII
Dim s As String = enc.GetString(rdo.buffer, 0, bytesRead)
CmdOutput.Invoke(UpdateCmdOutputDelegate, New Object() {s})
StartConsoleRead(rdo.s)
End Sub
Public Class ReadData
Public buffer(20480) As Byte
Public s As Stream
End Class
Also, you're Timer.Interval on the progress bar form should not be 1. Make it something more reasonable, like 250 to 500 (quarter to half a second). Setting it to one will just make your app hog the CPU.
|
|
|
|
|
If I don't start the process, the progressbar in the form works fine. So the p.Start action hang the progressbar form.
Private Sub Run_FAST_Tool()
Dim sAppPath As String = ".\FAST.exe"
Dim fileName As String = objFASTPrimaryData.FASTPrimaryFileName_FST
Dim p As New System.Diagnostics.Process()
Dim rtnStr As String = String.Empty
p.StartInfo.FileName = Application.StartupPath & "\" & sAppPath
p.StartInfo.Arguments = fileName
'Do not use the system shell to start the program this is so we can hide the command dos window
p.StartInfo.UseShellExecute = False
p.StartInfo.WorkingDirectory = strOutputFilePath
' Show no dos window if false
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardOutput = True
Dim progBarFrm As New FormProgressBar
progBarFrm.Show()
end sub
|
|
|
|
|
The reason why your UI thread blocks is not because you started the process. It's blocking because of another line AFTER your call to Start. Your executing some statement that blocks, like WaitForExit, freezing your UI. You cannot do that and expect your UI to update itself.
|
|
|
|
|
Thanks, David.
After I remove calling WaitForExit() and ReadToEnd(), the progressbar works now, but the Exited event function OnProcesited is not called, so the progressbar is always shown. How can I make OnProcesited() be called?
Private Sub OnProcesited(ByVal sender As Object, ByVal e As System.EventArgs)
Dim p As System.Diagnostics.Process
p = sender
Dim rtnStr As String = String.Empty
rtnStr = p.StandardOutput.ReadToEnd()
If rtnStr.Contains(" FAST terminated normally.") = True Then
rtnStr = rtnStr & vbCrLf & "Please click Postprocess -> View Output File in menu to view the file."
updateViewMenu()
End If
progBarFrm.Close()
progBarFrm.Dispose()
Dim frm As New FormShowFASTResult
frm.txtFASTResult.Text = rtnStr
frm.Button1.Select()
frm.ShowDialog()
End Sub
Private Sub Run_Tool()
Dim sAppPath As String = ".\XXXXX.exe"
Dim fileName As String = "XXXXX.txt"
Dim p As New System.Diagnostics.Process()
p.StartInfo.FileName = Application.StartupPath & "\" & sAppPath
p.StartInfo.Arguments = fileName
'Do not use the system shell to start the program this is so we can hide the command dos window
p.StartInfo.UseShellExecute = False
p.StartInfo.WorkingDirectory = strOutputFilePath
' Show no dos window if false
p.StartInfo.CreateNoWindow = True
p.StartInfo.RedirectStandardOutput = True
p.EnableRaisingEvents = True
AddHandler p.Exited, AddressOf OnProcesited
progBarFrm = New FormProgressBar
Try
p.Start()
progBarFrm.Show()
progBarFrm.Refresh()
Catch ex As Exception
ShowValidationMessage("Unexception error is caught, please close and try again.", "Error")
Return
End Try
End Sub
|
|
|
|
|
You can't force it. Your external process just hasn't stopped yet for some reason. Does your external process wait for the user to "Press any key to exit"?? I sure hope not!
|
|
|
|
|
I have an vb.net application that is being used by multi-users. I execute all sql statements in a seperate block all at one time one after another. Many times it so happens that 2 records (referrenced by 2 persons) are stored in a single id which should be stored in different id.
What should I do to avoid this type of conflict ?
Thanks & Regards,
|
|
|
|
|
Use identity columns so that the ID's are generated automatically.
|
|
|
|
|
Thanks AspDotNetDev, Its a high-end reqd to generate ID programmatically and not auto.
Thanks & Regards,
|
|
|
|
|
tell your customer that he made an request which is VERY EXPANSIVE to handle - he will agree with identity columns.
I cannot remember: What did I before google?
|
|
|
|
|
Well, then you have a serious design flaw in your database. One which will take a redesign to fix and a major overhaul of your code.
|
|
|
|
|
Thanks AspDotNet, Thomas, Dave.
>>One which will take a redesign to fix and a major overhaul of your code.
Dave, can you explain a bit on what are you trying to say and how and what factors to look for in the code.
Thanks & Regards,
|
|
|
|
|
Simple. Either you don't have a valid primary key (for example, the VIN is unique to each car, but you should never use it as a primary key) or your code is generating the key values (REALLY bad idea!).
In order to fix this you are either going to have to add proper primary keys to your tables, and update your code accordingly or you're going to have to add a layer to your database where every instance of your app is going to have to go through a singleton running on a server to have a primary key generated. Only one instance of your app is going to be able to call this singleton at a time which is going to kill your scalability. Oh, and you're still going to have to update your code to support this.
|
|
|
|
|
Thanks Dave for clean and clear explaination and how should I handle this.
Thanks & Regards,
|
|
|
|
|
hello guys,
i'm new to VB6 and crystal report, can somebody give tutorial on how to get a value from a textbox to be used in generating a report. this must be done when a button is click.
the scenerio is like this:
i have two textboxes(the from and to date) and a button. below is a crystal report viewer. what i want to do is to generate a report base from the from and to date. i hope you've got what i mean.
any help is appreciated. thanks and God Bless!
|
|
|
|
|
Don't repost your question.
I have answered your question in Q/A section. Clickety[^]
|
|
|
|
|
hey thatraja, do you know how to do this in vb6?
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim cryRpt As New ReportDocument
cryRpt.Load("PUT CRYSTAL REPORT PATH HERE\CrystalReport1.rpt")
Dim crParameterFieldDefinitions As ParameterFieldDefinitions
Dim crParameterFieldDefinition As ParameterFieldDefinition
Dim crParameterValues As New ParameterValues
Dim crParameterDiscreteValue As New ParameterDiscreteValue
crParameterDiscreteValue.Value = TextBox1.Text
crParameterFieldDefinitions = -
cryRpt.DataDefinition.ParameterFields
crParameterFieldDefinition = _
crParameterFieldDefinitions.Item("Customername")
crParameterValues = crParameterFieldDefinition.CurrentValues
crParameterValues.Clear()
crParameterValues.Add(crParameterDiscreteValue)
crParameterFieldDefinition.ApplyCurrentValues(crParameterValues)
CrystalReportViewer1.ReportSource = cryRpt
CrystalReportViewer1.Refresh()
End Sub
|
|
|
|
|
|
im having problem displaying the from and to statement. my report doesn't show anyrecord at all.
my selection formula record goes like this:
{Users.DateRegistered} >="{?FromDate}" and {Users.DateRegistered} <="{?ToDate}"
the two parameter fields(?FromDate and ?ToDate are both date type).
reportname: Report_DateFromTo
my vb code:
<br />
<br />
Report_DateFromTo.ParameterFields.Item(1).AddCurrentValue Me.DTPicker1.Value<br />
Report_DateFromTo.ParameterFields.Item(2).AddCurrentValue Me.DTPicker2.Value<br />
Me.CRViewer1.ReportSource = Report_DateFromTo<br />
Me.CRViewer1.ViewReport<br />
<br />
<br />
thanks
|
|
|
|
|
i made it!!! thankyou LORD!!! HE's really great!!!
|
|
|
|