如何在bat文件中找到正在运行的进程

时间:2016-09-07 16:50:13

标签: vb.net windows batch-file process

我有一个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。好吧,我想要一个窗口,只需最小化到任务栏。如果有人说了一些简单的话,我会把它放在这个帖子上。我还会做更多谷歌,但如果我找不到任何相关内容,我将开始一个新的主题。 现在我将它打开,只是因为它将在一个地方,但看起来我带着窗口标题进行修复。

1 个答案:

答案 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