无法最小化进程启动上的新进程窗口



我需要从程序中启动一个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

一切正常,但窗口没有最小化
如何最小化窗口?

一种可能的方法是,当Java.exe出现时,使用UI Automation最小化它生成的窗口
启动进程时,将执行Jar文件并创建一个新窗口。该窗口有一个特定的类名SunAwtFrame:该值可用于识别窗口,然后访问UI Automation元素的WindowPattern并调用其SetWindowVisualState((方法以最小化窗口。

您也可以使用"窗口标题"属性,以防在此处进行更好的选择。在这种情况下,用于标识窗口的PropertyCondition是NameProperty,而不是ClassNameProperty:

window = AutomationElement.RootElement.FindFirst(TreeScope.Children, New PropertyCondition(
AutomationElement.NameProperty, "[The Window Title]"))

当然,这个过程是完全有效的。

在这里,我使用异步变体实现了它,重定向StandardOutput和StandardError,还启用并订阅了Exited事件,设置了[Process].EnableRaisingEvents = True
Exited事件会在进程关闭时发出通知,同时还会处理进程对象。


此处的代码使用StopWatch来等待进程窗口显示,因为Process.WaitForInputIdle()可能不是
如果3000毫秒的间隔太短或太长,请调整代码
但是,请注意,只要窗口出现,While循环就会退出。

此代码需要对UIAutomationClientUIAutomationTypes程序集的引用。

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

最新更新