我有一个vb.net程序,它监视一个事件,然后用该事件执行相关的程序。然后监视任务,如果它意外停止,则重新启动它。所有这一切都有效,但我试图使程序足够智能,如果控制程序停止并重新启动,当其中一个现有事件正在运行时,它将找到正确的任务,然后开始监视它。 我做了一个Process.GetProcess并循环查看MainModule.Filename。这适用于.exe,但在启动.bat文件时,文件名为“cmd.exe”。
我可以使用哪些其他属性来匹配正在运行的任务?
基本启动任务:
Dim psi As New ProcessStartInfo()
psi.FileName = tmpProgramToExcute
psi.UseShellExecute = True
psi.Arguments = tmpCommandLineOptions
psi.Verb = "runas"
psi.WindowStyle = tmpWindowStyle
tmpTask = New Process
tmpTask.StartInfo = psi
tmpTask.Start()
搜索代码:
If (tmpTask IsNot Nothing) AndAlso tmpTask.HasExited Then
tmpTask.Dispose()
tmpTask = Nothing
End If
Dim tmpProcess() As Process = Process.GetProcesses
For xLoop_tmpProcess As Integer = 0 To tmpProcess.Count - 1
Try
If tmpProcess(xLoop_tmpProcess).MainModule.FileName.ToLower = tmpProgramToExcute.ToLower Then
tmpTask = tmpProcess(xLoop_tmpProcess)
NewProcessingList(tmpKey).Task = tmpTask
Exit For
End If
Catch ex As Exception
End Try
Next
Updated 9/8/2016 12:39 pm当地时间 我回到了我的旧vb6程序,这是我正在替换的程序,是在2003年编写的。我的黑盒功能之一就是启动一个程序。就是这样:
Function StartPrg(PrgName As String, Optional tmpText As String = "", Optional WindowState As WindowStyle = 4, Optional CmdPram As String = "") As Long
'0 hidden and focus is passed to the hidden window.
'1 Has focus and is restored to its original size and position.
'2 Is displayed as an icon with focus (minimized).
'3 Is maximized with focus.
'4 Is restored to its most recent size and position. No Focus.
'6 Is displayed as an icon. No Focus.
Dim tmpPID As Long
Dim xLoop As Long
Dim yLoop As Long
Dim PrgStarted As Boolean
'Log.It "Try to start " + PrgName
'tmpPID = Shell(PrgName, WindowState)
Dim Ret As Integer
Dim Bfr As String
Dim ExPath As String
Dim Ext As String
'If Dir(PrgName) = "" Or PrgName = "" Then
' StartPrg = -1
' Exit Function
'End If
If Ext = ".EXE" Or Ext = ".COM" Or Ext = ".BAT" Then
tmpPID = Shell(PrgName + " " + CmdPram, WindowState)
Else
Bfr = String(300, 32)
Ext = UCase(Right$(PrgName, 4))
Ret = FindExecutable(PrgName, vbNullString, Bfr)
If Ret > 32 Then
ExPath = Left$(Bfr, InStr(Bfr, Chr$(0)) - 1)
tmpPID = Shell(ExPath + " " + CmdPram, WindowState)
Else
StartPrg = -1
Exit Function
End If
End If
'Log.It PrgName + " started"
For xLoop = 1 To 10
DoEvents
If PrgStarted Then Exit For
For xSleepLoop = 1 To 100
PrgStarted = PrgExist(tmpPID)
If PrgStarted Then Exit For
Sleep 10
DoEvents
Next xSleepLoop
Next
If xLoop < 11 Then
MyPID = tmpPID
fEnumWindows
If Len(tmpText) > 0 Then
For xLoop = 1 To OnWin
If MyWinList(1, xLoop) = tmpPID Then
SendMessageA MyWinList(2, xLoop), WM_SETTEXT, 0&, tmpText
DoEvents
Sleep 10
End If
Next
End If
StartPrg = tmpPID
Else
StartPrg = -1
Exit Function
End If
End Function
所以我试图在vb.net中重新定位它:
Public Function ShellAndNotWait(ByVal sFilePath As String,
Optional ByVal sCommandLineOptions As String = "",
Optional ByRef sStdOut As Boolean = False,
Optional ByRef sStdError As Boolean = False,
Optional pWindowStyle As eShellWindowStyle = eShellWindowStyle.RecentSizeNoFocus,
Optional pWindowName As String = "") As Process
Dim psi As New ProcessStartInfo()
psi.FileName = sFilePath
psi.UseShellExecute = (Not (sFilePath.ToUpper.EndsWith(".EXE") Or sFilePath.ToUpper.EndsWith(".COM") Or sFilePath.ToUpper.EndsWith(".BAT")))
psi.Arguments = sCommandLineOptions
psi.RedirectStandardOutput = sStdOut
psi.RedirectStandardError = sStdError
psi.CreateNoWindow = sStdOut Or sStdError
Select Case pWindowStyle
Case eShellWindowStyle.HiddenFocus
psi.WindowStyle = ProcessWindowStyle.Hidden
Case eShellWindowStyle.IconFocus Or
eShellWindowStyle.IconNoFocus
psi.WindowStyle = ProcessWindowStyle.Minimized
Case eShellWindowStyle.RecentSizeFocus Or
eShellWindowStyle.RecentSizeNoFocus
psi.WindowStyle = ProcessWindowStyle.Normal
Case eShellWindowStyle.MaximizedFocus
psi.WindowStyle = ProcessWindowStyle.Maximized
End Select
Dim proc As New Process
proc.StartInfo = psi
proc.Start()
If proc Is Nothing Then Return Nothing
Sleep(100)
If pWindowName.Length > 0 Then SetWindowText(proc.MainWindowHandle, pWindowName)
If pWindowStyle = eShellWindowStyle.HiddenFocus OrElse
pWindowStyle = eShellWindowStyle.IconFocus OrElse
pWindowStyle = eShellWindowStyle.MaximizedFocus OrElse
pWindowStyle = eShellWindowStyle.RecentSizeFocus Then
AppActivate(proc.Id)
End If
Return proc
End Function
我可以设置所有有效的标题。然后只要它是唯一的,我就可以再次找到任务并假设任务就像我从一开始就开始它一样。 我的问题是VB6 shell有6种启动窗口的模式而.Net没有。我试图模仿其中一些,但将startinfo windowstyle设置为最小化不起作用。在谷歌之后看起来如果你正在启动cmd.exe,它会忽略&#34;提示&#34;。很多帖子都是关于隐藏窗口的,因此修复程序将CreateWindow设置为false。好吧,我想要一个窗口,只需最小化到任务栏。如果有人说了一些简单的话,我会把它放在这个帖子上。我还会做更多谷歌,但如果我找不到任何相关内容,我将开始一个新的主题。 现在我将它打开,只是因为它将在一个地方,但看起来我带着窗口标题进行修复。
答案 0 :(得分:0)
底线...... 为了找到我开始的现有应用程序,但是因为启动它的应用程序本身重新启动了orphen,我选择了窗口标题。因此规则是,此应用管理的所有窗口标题必须是唯一的。
更多细节.... 我想要一个程序来管理程序列表,我称之为服务,但它们不是真正的窗口服务,它们只是简单的程序和批处理文件,如果它们停止,它们将被重新启动。我带了一个窗口应用程序,所以我可以有一些GUI来启动/停止,如果一个程序被声明隐藏,它可以被显示。所以我创建了一个跟踪所需信息的类(clsServiceList),然后将其添加到调用lstServices列表中(lstServices =新列表(clsServiceList))。有两个主要的子服务“ServiceUpdate”和“StartService”。在调用ServiceUpdate之后,lstServices的所有状态(属性)都应该是最新的。这可以在启动时调用以查找orphen任务,或者每隔几秒钟调用一次,以查看是否需要重新启动。这个线程的一部分是找到一种设置窗口标题的方法,然后管理窗口样式。所以这里是代码,如果我需要添加它只是让我知道。谢谢大家的帮助。
Private Class clsServiceList
';0 hidden And focus Is passed to the hidden window.
';1 Has focus And Is restored to its original size And position.
';2 Is displayed as an icon with focus (minimized).
';3 Is maximized with focus.
';4 Is restored to its most recent size And position. No Focus.
';6 Is displayed as an icon. No Focus.
Public ProcessName As String
Public ProgramToExcute As String
Public CommandLineOptions As String
Public Task As Process = Nothing
Public WindowTitle As String = ""
Public WindowStyle As eShellWindowStyle = eShellWindowStyle.RecentSizeNoFocus
Public HowRun As String = "" 'KR keep running or JS just once
Public IsWindowIconic As Boolean = False
Public IsWindowVisible As Boolean = False
Public IsWindowZoomed As Boolean = False
Public IsWindowNormal As Boolean = False
Sub New(pProcessName As String,
pProgramToExcute As String,
pCommandLineOptions As String,
pWindowTitle As String,
pWindowStyle As String,
pHowRun As String)
Me.ProcessName = pProcessName
Me.ProgramToExcute = pProgramToExcute
Me.CommandLineOptions = pCommandLineOptions
WindowStyle = CType(CIntNull(pWindowStyle), eShellWindowStyle)
WindowTitle = pWindowTitle
HowRun = pHowRun
End Sub
End Class
End Class
Private Sub ServicesUpdate()
Dim tmpProcess() As Process = Process.GetProcesses
For xLoop_Services As Integer = 0 To lstServices.Count - 1
For xLoop_Process As Integer = 0 To tmpProcess.Count - 1
If tmpProcess(xLoop_Process).MainWindowTitle = lstServices(xLoop_Services).WindowTitle Then
If lstServices(xLoop_Services).Task Is Nothing Then lstServices(xLoop_Services).Task = tmpProcess(xLoop_Process)
lstServices(xLoop_Services).IsWindowIconic = IsWindowIconic(lstServices(xLoop_Services).Task.MainWindowHandle)
lstServices(xLoop_Services).IsWindowZoomed = IsWindowZoomed(lstServices(xLoop_Services).Task.MainWindowHandle)
lstServices(xLoop_Services).IsWindowNormal = IsWindowNormal(lstServices(xLoop_Services).Task.MainWindowHandle)
lstServices(xLoop_Services).IsWindowVisible = IsWindowVisible(lstServices(xLoop_Services).Task.MainWindowHandle)
End If
Next
Next
End Sub
Public Function IsWindowIconic(ByVal hWnd As IntPtr) As Boolean
Return ((GetWindowLong(hWnd, WindowLongFlags.GWL_STYLE) And WS_MINIMIZE) = WS_MINIMIZE)
End Function
Public Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
Return ((GetWindowLong(hWnd, WindowLongFlags.GWL_STYLE) And WS_VISIBLE) = WS_VISIBLE)
End Function
Public Function IsWindowZoomed(ByVal hWnd As IntPtr) As Boolean
Return ((GetWindowLong(hWnd, WindowLongFlags.GWL_STYLE) And WS_MAXIMIZE) = WS_MAXIMIZE)
End Function
Public Function IsWindowNormal(ByVal hWnd As IntPtr) As Boolean
Return Not (IsWindowIconic(hWnd) Or IsWindowZoomed(hWnd))
End Function
<DllImport("user32.dll", SetLastError:=True)>
Private Function GetWindowLong(hWnd As IntPtr,
<MarshalAs(UnmanagedType.I4)> nIndex As WindowLongFlags) As Integer
End Function
Public Enum WindowLongFlags As Integer
GWL_EXSTYLE = -20
GWLP_HINSTANCE = -6
GWLP_HWNDPARENT = -8
GWL_ID = -12
GWL_STYLE = -16
GWL_USERDATA = -21
GWL_WNDPROC = -4
DWLP_USER = &H8
DWLP_MSGRESULT = &H0
DWLP_DLGPROC = &H4
End Enum
' Window Styles
Const WS_OVERLAPPED As UInt32 = 0
Const WS_POPUP As UInt32 = &H80000000&
Const WS_CHILD As UInt32 = &H40000000
Const WS_MINIMIZE As UInt32 = &H20000000
Const WS_VISIBLE As UInt32 = &H10000000
Const WS_DISABLED As UInt32 = &H8000000
Const WS_CLIPSIBLINGS As UInt32 = &H4000000
Const WS_CLIPCHILDREN As UInt32 = &H2000000
Const WS_MAXIMIZE As UInt32 = &H1000000
Const WS_CAPTION As UInt32 = &HC00000 ' WS_BORDER or WS_DLGFRAME
Const WS_BORDER As UInt32 = &H800000
Const WS_DLGFRAME As UInt32 = &H400000
Const WS_VSCROLL As UInt32 = &H200000
Const WS_HSCROLL As UInt32 = &H100000
Const WS_SYSMENU As UInt32 = &H80000
Const WS_THICKFRAME As UInt32 = &H40000
Const WS_GROUP As UInt32 = &H20000
Const WS_TABSTOP As UInt32 = &H10000
Const WS_MINIMIZEBOX As UInt32 = &H20000
Const WS_MAXIMIZEBOX As UInt32 = &H10000
Const WS_TILED As UInt32 = WS_OVERLAPPED
Const WS_ICONIC As UInt32 = WS_MINIMIZE
Const WS_SIZEBOX As UInt32 = WS_THICKFRAME
' Extended Window Styles
Const WS_EX_DLGMODALFRAME As UInt32 = &H1
Const WS_EX_NOPARENTNOTIFY As UInt32 = &H4
Const WS_EX_TOPMOST As UInt32 = &H8
Const WS_EX_ACCEPTFILES As UInt32 = &H10
Const WS_EX_TRANSPARENT As UInt32 = &H20
Const WS_EX_MDICHILD As UInt32 = &H40
Const WS_EX_TOOLWINDOW As UInt32 = &H80
Const WS_EX_WINDOWEDGE As UInt32 = &H100
Const WS_EX_CLIENTEDGE As UInt32 = &H200
Const WS_EX_CONTEXTHELP As UInt32 = &H400
Const WS_EX_RIGHT As UInt32 = &H1000
Const WS_EX_LEFT As UInt32 = &H0
Const WS_EX_RTLREADING As UInt32 = &H2000
Const WS_EX_LTRREADING As UInt32 = &H0
Const WS_EX_LEFTSCROLLBAR As UInt32 = &H4000
Const WS_EX_RIGHTSCROLLBAR As UInt32 = &H0
Const WS_EX_CONTROLPARENT As UInt32 = &H10000
Const WS_EX_STATICEDGE As UInt32 = &H20000
Const WS_EX_APPWINDOW As UInt32 = &H40000
Const WS_EX_OVERLAPPEDWINDOW As UInt32 = (WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE)
Const WS_EX_PALETTEWINDOW As UInt32 = (WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST)
Const WS_EX_LAYERED As UInt32 = &H80000
Const WS_EX_NOINHERITLAYOUT As UInt32 = &H100000 ' Disable inheritence of mirroring by children
Const WS_EX_LAYOUTRTL As UInt32 = &H400000 ' Right to left mirroring
Const WS_EX_COMPOSITED As UInt32 = &H2000000
Const WS_EX_NOACTIVATE As UInt32 = &H8000000
Private Sub StartService(pServiceNumber As Integer)
If Path.GetFileName(lstServices(pServiceNumber).ProgramToExcute) = lstServices(pServiceNumber).ProgramToExcute Then
Dim tmpPath As String = Space(300)
Dim tmpValue As Long = FindExecutable(lstServices(pServiceNumber).ProgramToExcute, vbNullString, tmpPath)
If tmpValue > 32 Then
lstServices(pServiceNumber).ProgramToExcute = tmpPath.Substring(0, tmpPath.IndexOf(vbNullChar))
End If
End If
Dim tmpProcess As Process = ShellAndNotWait(lstServices(pServiceNumber).ProgramToExcute,
lstServices(pServiceNumber).CommandLineOptions,
False, False,
lstServices(pServiceNumber).WindowStyle,
lstServices(pServiceNumber).WindowTitle)
lstServices(pServiceNumber).Task = tmpProcess
lstServices(pServiceNumber).IsWindowIconic = IsWindowIconic(lstServices(pServiceNumber).Task.MainWindowHandle)
lstServices(pServiceNumber).IsWindowZoomed = IsWindowZoomed(lstServices(pServiceNumber).Task.MainWindowHandle)
lstServices(pServiceNumber).IsWindowNormal = IsWindowNormal(lstServices(pServiceNumber).Task.MainWindowHandle)
lstServices(pServiceNumber).IsWindowVisible = IsWindowVisible(lstServices(pServiceNumber).Task.MainWindowHandle)
If lstServices(pServiceNumber).WindowTitle.Length = 0 Then lstServices(pServiceNumber).WindowTitle = tmpProcess.MainWindowTitle
End Sub
Public Function ShellAndNotWait(ByVal sFilePath As String,
Optional ByVal sCommandLineOptions As String = "",
Optional ByRef sStdOut As Boolean = False,
Optional ByRef sStdError As Boolean = False,
Optional pWindowStyle As eShellWindowStyle = eShellWindowStyle.RecentSizeNoFocus,
Optional pWindowName As String = "") As Process
Dim psi As New ProcessStartInfo()
psi.FileName = sFilePath
psi.UseShellExecute = (Not (sFilePath.ToUpper.EndsWith(".EXE") Or sFilePath.ToUpper.EndsWith(".COM") Or sFilePath.ToUpper.EndsWith(".BAT")))
psi.Arguments = sCommandLineOptions
psi.RedirectStandardOutput = sStdOut
psi.RedirectStandardError = sStdError
psi.CreateNoWindow = sStdOut Or sStdError
Dim proc As New Process
proc.StartInfo = psi
proc.Start()
If proc Is Nothing Then Return Nothing
Sleep(100)
If pWindowName.Length > 0 Then SetWindowText(proc.MainWindowHandle, pWindowName)
Select Case pWindowStyle
Case eShellWindowStyle.HiddenFocus Or eShellWindowStyle.HiddenFocus
ShowWindow(proc.MainWindowHandle, eSHOW_WINDOW.SW_HIDE)
Case eShellWindowStyle.IconFocus Or eShellWindowStyle.IconNoFocus
ShowWindow(proc.MainWindowHandle, eSHOW_WINDOW.SW_MINIMIZE)
Case eShellWindowStyle.MaximizedFocus
ShowWindow(proc.MainWindowHandle, eSHOW_WINDOW.SW_MAXIMIZE)
Case eShellWindowStyle.RecentSizeFocus Or eShellWindowStyle.RecentSizeNoFocus
ShowWindow(proc.MainWindowHandle, eSHOW_WINDOW.SW_NORMAL)
End Select
If pWindowStyle = eShellWindowStyle.HiddenFocus OrElse
pWindowStyle = eShellWindowStyle.IconFocus OrElse
pWindowStyle = eShellWindowStyle.MaximizedFocus OrElse
pWindowStyle = eShellWindowStyle.RecentSizeFocus Then
AppActivate(proc.Id)
End If
Return proc
End Function
<DllImport("shell32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Function FindExecutable(ByVal lpFile As String,
ByVal lpDirectory As String,
ByVal lpResult As String) As Long
End Function
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As eSHOW_WINDOW) As Integer
End Function
<Flags()>
Public Enum eSHOW_WINDOW As Integer
SW_HIDE = 0
SW_SHOWNORMAL = 1
SW_NORMAL = 1
SW_SHOWMINIMIZED = 2
SW_SHOWMAXIMIZED = 3
SW_MAXIMIZE = 3
SW_SHOWNOACTIVATE = 4
SW_SHOW = 5
SW_MINIMIZE = 6
SW_SHOWMINNOACTIVE = 7
SW_SHOWNA = 8
SW_RESTORE = 9
SW_SHOWDEFAULT = 10
SW_FORCEMINIMIZE = 11
SW_MAX = 11
End Enum