When I want to display message I'm calling Message Display sub program(EXE) from my main Program (calling program). I cannot get called exe dialog result to caller.
Dim psiProcessInfo As New ProcessStartInfo
With psiProcessInfo
.FileName = "DisplayMessage"
.Arguments = ("FormName$C$lblMessageLine01$lblMessageLine02$lblMessageLine03")
End With
Process.Start(psiProcessInfo)
above I display calling section.
Private Sub dlgDisplayMessage_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Input Parameter Accepted
strInputMessage = Command()
' Composite Parameter Seperator
Dim strParaSeperator As String = "$"
Dim strCompersitePara As String = Microsoft.VisualBasic.Interaction.Command
' Parameter Split & Assign To Array
Dim arParameter() As String = strCompersitePara.Split(strParaSeperator.ToCharArray)
With pbPictureBox
Select Case lblMessageType.Text
Case Is = "C" ' Critical
.Image = My.Resources.Critical
Case Is = "E" ' Exclamation
.Image = My.Resources.Exclamation
Case Is = "Q" ' Question
.Image = My.Resources.Question
End Select
.Visible = True
End With
With txtMessageBody
.Multiline = True
.Size = New Size(386, 215)
.Location = New Point(24, 53)
.ScrollBars = ScrollBars.Vertical
.TextAlign = HorizontalAlignment.Center
.Text = vbCrLf & _
lblMessageLine01.Text.Trim & _
vbCrLf & vbCrLf & _
lblMessageLine02.Text.Trim & _
vbCrLf & vbCrLf & _
lblMessageLine03.Text.Trim
.Visible = True
End With
With cmdCancel
.Focus()
End With
End Sub
Private Sub cmdYes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdYes.Click
Me.DialogResult = System.Windows.Forms.DialogResult.Yes
End Sub
Private Sub cmdCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCancel.Click
Try
Me.DialogResult = Windows.Forms.DialogResult.No
End Sub
Display message dialog coding I display above. I want to know how I get DialogResult.OK or DialogResult.No to calling exe.
Edited
According to the Jimi I change my caller program code. But still it didnt return any value.
Dim p As New Process()
p.StartInfo.UseShellExecute = False
p.StartInfo.ErrorDialog = True
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.UseShellExecute = False
p.StartInfo.Arguments = ("FormName$C$lblMessageLine01$lblMessageLine02$lblMessageLine03")
p.StartInfo.FileName = "DisplayMessage"
p.Start()
Dim output As String = p.StandardOutput.ReadToEnd()
p.WaitForExit()
MessageBox.Show(output)
A few suggestions about the way the
dlgDisplayMessageForm handles the CommandLine arguments:You should use Environment.GetCommandLineArgs() to get an array of values passed to the command line. These values are meant to be separated by a space.
The first item always represents the executable path. Recommended, it's a .Net method, much easier to translate to another .Net language.
You could also use My.Application.CommandLineArgs, the difference is that the first item is the first parameter of the command line, not the executable path. Avoid
Interaction.Command()I think that those
lblMessageLine01etc. parts are actually meant to be the content of some Labels. In this case, you should of course use thelblMessageLine01.Textproperty. You can use an interpolated string to add these values to the command line. Since these Labels may contain multiple words separated by a space, you need to enclose these values in double quotes. For example:To return a value from the Dialog, using the Process class, you have a few options:
Console.WriteLine()/Console.Out.WriteLine()StreamWriter.WriteLine()Of course you could also use some form of Interprocess Communications, but this a different scenario than what described in the OP.
The application that starts this executable can get the outcome of the Dialog in different ways: reading the StandardOutput, StandardError or ExitCode of the Process it launched. Or all of them, of course.
I assume the application that creates this Dialog is under your control (you made it).
In any case, the Process StartInfo must set RedirectStandardOutput to
True, optionally RedirectStandardError toTrueand UseShellExecute toFalse(starting with the System Shell doesn't allow redirections here)You can then:
Start the Process
Read the StandardOutput and StandardError
Wait synchronously for the Process to exit, using Process.WaitForExit()
Read the Process
ExitCode, e.g.:This procedure is synchronous (blocking). There's a good chance you don't want this when the Process is started and its results waited in a GUI, since it will also block the User Interface.
Of course you could run a Task or start a Thread, then marshal back the results to the UI Thread.
You can also use the asynchronous (event-driven) version, subscribing to the OutputDataReceived, ErrorDataReceived and Exited events.
To enable the
Exitedevent, you need to set Process.EnableRaisingEvents toTrue.Also setting the Process.SynchronizingObject to the instance of a Control class (usually a Form, but any
ISynchronizeInvokeobject would do) that will handle the events. This because the Process' events are raised in ThreadPool Threads. Setting a UI element as theSynchronizingObject, causes the events to raise in the same Thread where object specified was created (the UI Thread, here).This can be somewhat obnoxious in existing contexts, because you have to add the event handlers to a Form class, remember to remove them, dispose of the Process
asynchronouslyetc.So here's a helper class that transforms the event-driven procedure in an awaitable Task that can be executed from any async method. E.g., it can be called from the
Clickevent handler of a Button, adding theAsynckeyword to the method.It can be modified and used to test different scenarios and methods to start a Process and get its results in a separate environment.
It uses a TaskCompletionSource + Task.WhenAny().
The
Exitedevent causes theTaskCompletionSourceto set its result.The helper class returns the contents of the Process' StandardOutput, StandardError and ExitCode value translated to a DialogResult value.
It can set a Timeout, to stop waiting for the Process to return a result, if specified.
Sample calling procedure:
If the Interpolated Strings feature is not available, use
String.Format()instead:DialogResponseHelperclass: