A possible approach is to minimize the Window generated by Java.exe
, when it shows up, using UI Automation.
When the Process is started, the Jar
file is executed and a new Window is created. This Window has a specific class name, SunAwtFrame
: this value can be used to identify the window, then access the UI Automation Element's WindowPattern and call its SetWindowVisualState() method to minimize the Window.
You can also use the Window Title property, in case its a better choice here. In this case, the PropertyCondition to identify the Window is the NameProperty instead of the ClassNameProperty:
window = AutomationElement.RootElement.FindFirst(TreeScope.Children, New PropertyCondition(
AutomationElement.NameProperty, "[The Window Title]"))
Of course, the Process is perfectly functional.
Here, I've implemented it using the asynchronous variant, redirecting StandardOutput and StandardError, also enabling and subscribing to the Exited
event, setting [Process].EnableRaisingEvents = True
.
The Exited
events notifies when the Process is closed and also disposes of the Process object.
The code here uses a StopWatch to wait for the Process' Window to show up, since Process.WaitForInputIdle()
may not be get it right and complete too soon.
Adjust the code if 3000
milliseconds is a too short or too long interval.
Note, however, that as soon as the Window shows up, the While
loop is exited.
This code requires a reference to the UIAutomationClient
and UIAutomationTypes
assemblies.
Imports System.Windows.Automation
Dim proc As New Process()
Dim psInfo As New ProcessStartInfo() With {
.FileName = "java.exe",
.Arguments = "-jar YourJarFile.jar",
.WorkingDirectory = "[Your Jar File Path]",
.UseShellExecute = False,
.RedirectStandardOutput = True,
.RedirectStandardError = True
}
proc.EnableRaisingEvents = True
proc.StartInfo = psInfo
AddHandler proc.OutputDataReceived,
Sub(o, ev)
Console.WriteLine(ev.Data?.ToString())
End Sub
AddHandler proc.ErrorDataReceived,
Sub(o, ev)
Console.WriteLine(ev.Data?.ToString())
End Sub
AddHandler proc.Exited,
Sub(o, ev)
Console.WriteLine("Process Exited")
proc?.Dispose()
End Sub
proc.Start()
proc.BeginOutputReadLine()
Dim window As AutomationElement = Nothing
Dim sw1 As Stopwatch = New Stopwatch()
sw1.Start()
While True
window = AutomationElement.RootElement.FindFirst(
TreeScope.Children, New PropertyCondition(
AutomationElement.ClassNameProperty, "SunAwtFrame"))
If window IsNot Nothing OrElse sw1.ElapsedMilliseconds > 3000 Then Exit While
End While
sw1.Stop()
If window IsNot Nothing Then
DirectCast(window.GetCurrentPattern(WindowPattern.Pattern), WindowPattern).
SetWindowVisualState(WindowVisualState.Minimized)
End If