Мне нужно запустить java-процесс .jar
из моей программы.
После запуска я получаю результат и обрабатываю его.
Для этого я использую следующий код:
Dim p_Process As New Process()
Dim p_p As New ProcessStartInfo
p_p.FileName = "java.exe"
p_p.Arguments = "-jar myjar.jar"
p_p.WorkingDirectory = apppath & "\myFolder"
p_p.UseShellExecute = False
p_p.RedirectStandardOutput = True
p_p.WindowStyle = ProcessWindowStyle.Minimized
AddHandler p_Process.OutputDataReceived, AddressOf manageContent
p_Process.StartInfo = p_p
p_Process.Start()
p_Process.BeginOutputReadLine()
Мне нужны следующие строки, чтобы получить результат процесса для моего использования:
p_p.UseShellExecute = False
p_p.RedirectStandardOutput = True
Все работает, но окно не сворачивается.
Как свернуть окно?
1 ответ
Возможный подход - минимизировать окно, генерируемое Java.exe
, когда оно появляется, с помощью автоматизации пользовательского интерфейса.
Когда процесс запускается, выполняется файл Jar
и создается новое окно. Это окно имеет определенное имя класса, SunAwtFrame
: это значение можно использовать для идентификации окна, а затем получить доступ к WindowPattern и вызовите его SetWindowVisualState (), чтобы свернуть окно.
Вы также можете использовать свойство Window Title, если это лучший выбор здесь. В этом случае PropertyCondition для идентификации Окно вместо этого является NameProperty из ClassNameProperty:
window = AutomationElement.RootElement.FindFirst(TreeScope.Children, New PropertyCondition(
AutomationElement.NameProperty, "[The Window Title]"))
Конечно, процесс полностью функционален.
Здесь я реализовал его, используя асинхронный вариант, перенаправив StandardOutput и StandardError, а также включив событие Exited
и подписавшись на него, установив [Process].EnableRaisingEvents = True
.
События Exited
уведомляют о закрытии процесса, а также удаляют объект процесса.
В приведенном здесь коде используется секундомер, чтобы дождаться появления окна процесса, поскольку Process.WaitForInputIdle()
может быть неправильно и завершен слишком рано.
Измените код, если 3000
миллисекунды являются слишком коротким или слишком длинным интервалом.
Обратите внимание, однако, что как только появляется окно, цикл While
завершается.
Этот код требует ссылки на сборки UIAutomationClient
и UIAutomationTypes
.
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
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].