java - 无法最小化 Process.Start 上的新进程窗口
问题描述
我需要.jar
从我的程序中启动一个 java 进程。
一旦开始,我得到输出并处理它。
为此,我使用以下代码:
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()
我需要以下几行才能获得 Process 的输出以供我使用:
p_p.UseShellExecute = False
p_p.RedirectStandardOutput = True
一切正常,但窗口没有最小化。
如何最小化窗口?
解决方案
一种可能的方法是最小化由 生成的窗口Java.exe
,当它出现时,使用 UI 自动化。
当进程启动时,Jar
文件被执行并创建一个新窗口。这个窗口有一个特定的类名,SunAwtFrame
:这个值可以用来标识窗口,然后访问 UI 自动化元素的WindowPattern并调用它的SetWindowVisualState()方法来最小化窗口。
您还可以使用 Window Title 属性,以防它在这里是更好的选择。在这种情况下,标识 Window的PropertyCondition是NameProperty而不是ClassNameProperty:
window = AutomationElement.RootElement.FindFirst(TreeScope.Children, New PropertyCondition(
AutomationElement.NameProperty, "[The Window Title]"))
当然,该过程是完美的功能。
在这里,我使用异步变体实现了它,重定向 StandardOutput 和 StandardError,同时启用和订阅Exited
事件,设置[Process].EnableRaisingEvents = True
.
当Exited
Process 关闭时,事件会通知并处理 Process 对象。
此处的代码使用 StopWatch 来等待“进程”窗口出现,因为它Process.WaitForInputIdle()
可能无法正确完成并且过早完成。
如果3000
毫秒间隔太短或太长,请调整代码。
但是请注意,一旦 Window 出现,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
推荐阅读
- python - 在嵌套的“try”语句中,哪个“except”具有优先权?
- sql - 按“类型”列从表中获取数据时出现 SQL 错误
- jquery - 用淡入淡出替换 attr 链接 - jQuery
- javascript - 在 JavaScript 中设置 WebSocket Origin 标头
- ios - 当应用程序在 iOS 中以后台模式运行时进行 POST API 调用
- bash - 如何在带有目录列表的文本文件上使用 bash 树命令
- google-cloud-platform - GCP dataproc 上的外部 Hive 表未从 GCP 存储桶中读取数据
- c# - Linq Where 子句最终导致 NullReferenceException
- python - 使用 numpy 选择设置样本的最大替换次数
- c - Solving and fixing vulnerability pointed by the static analysis tool SPLINT