【发布时间】:2013-04-09 15:44:58
【问题描述】:
我正在寻找一种方法来执行 Steam (Steam.exe) 并等待它被加载(不退出)。
我认为一个好主意是列出所有子句柄并在标题句柄中搜索一个字符串,因为当 Steam 加载存在一个名为“Friends”的窗口句柄时,但这对我来说很难(API)所以也许存在一种等待程序加载的简单方法......
我将要做的示例:
' First process
Process.start("Process 1.exe")
' Here will goes an efficient method to wait for application is loaded,
' not sleeping X seconds measuring the loading time or any of that.
' Second process
' Depends on first process fully loaded.
' If first process is not fully loaded (libraries and that) then this process can't run.
Process.start("Processs 2.exe")
更新:
主要问题是如何等待 X 进程被加载,但关于 Steam.exe 我也注意到,当 Steam 加载时尝试读取/打开一些注册表项:
http://img267.imageshack.us/img267/6599/prtscrcapture4u.jpg
也许我可以用代码来监控其中一个 RegKeys 是否被访问?
像这样?:
Dim RegKey = "HKLM\...blablabla"
Process.start("steam.exe")
While not Regkey.IsAccessed
' Do nothing and wait
Loop
Process.start("Second process.exe")
更新 2:
我正在尝试通过引用 Amegon 的解决方案来制作一个函数,我没有完成代码,因为我在该行中遇到了错误:
Memory = hprocess.PrivateMemorySize64
但我只有在尝试启动“大”应用程序(需要很长时间才能加载的应用程序,如 Photoshop)时才会收到错误消息,而“小”应用程序运行良好。
如果有人可以帮助我简化/改进 Amegon 的解决方案以制作通用函数并纠正内存溢出错误...谢谢!
这是我的代码:
' This is the sub that launchs the unfinished function:
Private Sub Launch_Game()
'Wait_For_Application_To_Load("C:\Games\Steam.exe", "-applaunch 0")
Wait_For_Application_To_Load("C:\Program Files\Adobe Photoshop CS6 (64 Bit)\Photoshop.exe")
End Sub
Private Function Wait_For_Application_To_Load(ByVal APP_Path As String, Optional ByVal APP_Arguments As String = Nothing)
Dim File = My.Computer.FileSystem.GetFileInfo(APP_Path)
Process.Start(APP_Path, APP_Arguments)
Timer_CheckCPU.Tag = File.Name.Substring(0, File.Name.Length - 4) ' Photoshop
Timer_CheckCPU.Enabled = True
End Function
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
Private WithEvents Timer_CheckCPU As New Timer
Dim Memory_Value_Changed As Boolean
Dim CPU_Changed As Boolean
Dim CPU_Time As Boolean
Dim Running_Time As Boolean
Private _desiredTime_ms As Integer = 1500
Private Sub Timer_CheckCPU_Tick(sender As Object, ev As EventArgs) Handles Timer_CheckCPU.Tick
Timer_CheckCPU.Enabled = False
Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName(Timer_CheckCPU.Tag)
Dim hprocess As Process = pProcess(0)
If hprocess Is Nothing Then
Running = False
Timer_CheckCPU.Enabled = True
Return
End If
Running = True
' Here is the error:
Memory = hprocess.PrivateMemorySize64
' MsgBox(hprocess.PrivateMemorySize64.ToString)
CPUTotal = hprocess.TotalProcessorTime.TotalMilliseconds
If AllConditionsGood() Then
If Not (_countdown.IsRunning) Then
_countdown.Reset()
_countdown.Start()
End If
Dim _elapsed As Integer = _countdown.ElapsedMilliseconds
If _elapsed >= _desiredTime_ms Then
Me.TopMost = True
MsgBox("process loaded")
Return
End If
Else
_countdown.Reset()
End If
Timer_CheckCPU.Enabled = True
End Sub
Private Function AllConditionsGood() As Boolean
If CPU_Time Then Return False
If Memory_Value_Changed Then Return False
If Running_Time Then Return False
Return True
End Function
Private _countdown As New Stopwatch
Private _Running As Boolean = False
Public WriteOnly Property Running() As Boolean
Set(ByVal value As Boolean)
_Running = value
If value Then
Running_Time = False
Else
Running_Time = True
End If
End Set
End Property
Private _CPUTotal As Integer
Public WriteOnly Property CPUTotal() As Integer
Set(ByVal value As Integer)
CPU = value - _CPUTotal 'used cputime since last check
_CPUTotal = value
End Set
End Property
Private _CPU As Integer
Public WriteOnly Property CPU() As Integer
Set(ByVal value As Integer)
If value = 0 Then
CPU_Time = False
Else
CPU_Time = True
End If
_CPU = value
End Set
End Property
Private _Memory As Integer
Public WriteOnly Property Memory() As Integer
Set(ByVal value As Integer)
MemoryDiff = Math.Abs(value - _Memory)
_Memory = value
End Set
End Property
Private _MemoryDiff As Integer
Public WriteOnly Property MemoryDiff() As Integer
Set(ByVal value As Integer)
If value = _MemoryDiff Then
Memory_Value_Changed = False
Else
Memory_Value_Changed = True
End If
_MemoryDiff = value
End Set
End Property
【问题讨论】:
-
你检查过Process类的GetProcessesByName方法吗?只需尝试使用 ProcessExplorer 之类的工具来识别进程名称.....
-
如果您单击“处理”按钮,您会看到什么?您正在搜索进程而不是窗口
-
对不起,我是第一次使用 spy++,我已经编辑了我的问题!
-
我不确定是否可以使用 vb.net 监控其他程序 reg 密钥访问,但检查正在运行的窗口和这些窗口的子进程并不难。但我想任何事情都可能奏效,只要它能很好地提示加载已完成。由于好友列表自动登录可以被禁用,如果您扫描打开的好友列表,这将不是一个通用的解决方案
-
不,我的第一个想法是在加载 Steam 时扫描标题为“好友”的句柄,但该句柄并不指好友列表窗口自动登录(我不知道具体是哪个是引用),因为如果我使用任何自动日志选项(服务器、朋友、社区、商店等),句柄就存在。
标签: vb.net visual-studio handle window-handles