2016-09-07 11 views
0

私は、イベントを監視し、そのイベントで関連プログラムを実行するvb.netプログラムを持っています。タスクを監視し、予期せず停止した場合は再起動します。これはすべて機能しますが、プログラムをスマートにして、制御プログラムが停止して再起動したときに、既存のイベントの1つが実行されているときに、正しいタスクを見つけて監視を開始するようにしました。 私は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() 

:2016年9月8日12:39現地時間 を更新しました

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 

は、私は、戻って私の古いVB6のプログラムに行ってきました2003年に書かれたものです。私のブラックボックス機能の1つは、プログラムを開始することでした。これは、それは次のとおりです。

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でそれをreplcateしようとした:

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シェルには6つのモードがあり、.Netは起動しないということです。私はそれをエミュレートしようとしていましたが、最小化するためにstartinfoウィンドウスタイルを設定しても機能しません。あなたがcmd.exeを起動している場合のようにいくつかのGoogleの後、それは "ヒント"を無視します。多くの投稿がウィンドウを隠していたので、修正はCreateWindowをfalseに設定しました。まあ、私はウィンドウがほしい、ちょうどタスクバーに最小化する。誰かが何かシンプルなことを言うなら、私はこのスレッドに残します。また、私はいくつかのより多くのGoogleを行いますが、私はこれで何かを見つけることができない場合、私は新しいスレッドを開始します。 今のところ私はそれを開いたままにしているので、すべてが1か所にありますが、修正のためにウィンドウタイトルを表示したようです。

+0

バッチファイルのウィンドウタイトルを設定していますか? – Squashman

+2

バッチファイルをどのように起動しますか? 'start cmd/c%YourBatchFile%'のようなことをすることができます。これは、コマンドラインとして 'cmd/c%YourBatchFile%'を持つ新しい_cmd_プロセス(とウィンドウ)をバッチファイルで開始します。 – CristiFati

+0

@Squashman、いいえ、それは考えです。私は開始プロパティとしてそれが表示されませんが、私は勝利のAPIを持っています。私はタスクのタグプロパティがあることを望んだ。私は他の提案のいくつかを見てみましょう、私は戻ってくるでしょう。 – penright

答えて

0

ボトムライン.... 私が起動したアプリケーションを見つけるには、起動したアプリが再起動されたためにorphenだったので、ウィンドウタイトルを表示しました。したがってルールは、このアプリケーションが管理しているすべてのウィンドウタイトルは一意でなければなりません。

詳細... 私はプログラムのリストを管理するプログラムを望んでいたが、サービスを呼び出すが、真のウィンドウサービスではなく、単純なプログラムとバッチファイルであり、停止すれば再起動してください。私はウインドウアプリを使っていたので、何らかのGUIを起動/停止させることができ、プログラムが隠されていると見えるようにすることができました。そこで、必要な情報(clsServiceList)を追跡するためのクラスを作成し、それをlstServices(lstServices =新しいリスト(clsServiceListの))のリストに追加しました。主なサブサービス「ServiceUpdate」と「StartService」の2つがあります。 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 
関連する問題