【发布时间】:2016-09-07 16:50:13
【问题描述】:
我有一个 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
当地时间 2016 年 9 月 8 日下午 12:39 更新 我回到我的旧 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 窗口样式设置为最小化不起作用。经过一番谷歌搜索后,看起来如果您正在启动 cmd.exe,它会忽略“提示”。很多帖子都是关于隐藏窗口的,因此修复将 CreateWindow 设置为 false。好吧,我想要一个窗口,只需最小化到任务栏。如果有人说简单的话,我会把它留在这个线程上。另外我会做更多的谷歌,但如果我在这方面找不到任何东西,我会开始一个新的线程。 现在我将其保持打开状态,以便将其全部放在一个位置,但看起来我使用了修复的窗口标题。
【问题讨论】:
-
您是否正在为批处理文件设置窗口标题?
-
如何启动批处理文件?您可以执行类似
start cmd /c %YourBatchFile%的操作,这将启动批处理文件一个新的cmd 进程(和窗口),该进程将cmd /c %YourBatchFile%作为命令行。 -
@Squashman,不,但这是一个想法。我不认为这是一个启动属性,但是我确实有一个 win api。我希望有一个任务的标签属性。让我看看其他一些建议,我会回来的。
-
@CristiFati,我想过这个问题。通过指定 cmd 和路径,我可以切换到 UseShellExecute=False。缺点是我希望任务有自己的窗口。我可以使用环境变量来传递标签的好处。我尝试设置一个,但任务似乎没有拿起它。但是,如果我查看计算机-> 属性,它就在那里。我的批处理文件中有一个“set”命令来查看有哪些变量,但我没有看到它。我有一个 VB6 程序,用来做我正在尝试的事情,我想我需要找到它并看看我如何处理它。谢谢你和壁球侠。
-
在您的批处理文件中使用
TITLE命令,或者如果您使用cmd.exe 来START批处理文件,您也可以指定窗口标题。
标签: vb.net windows batch-file process