环境:vb.net,赢取表格和VS2010
我有两个应用程序A& B. B有两个从应用程序A打开的表单F1和F2。现在,下面的代码成功打开了应用程序B表单。我有一个非常具体的要求......
如果应用程序B-F1打开并且用户想要打开F2,则应用程序B会出现在前面,但F1仍然显示为当前表单。在下面的代码“IsProcessRunning”中,如果F2未打开,我可以检查并终止应用程序B进程,然后用F2重新打开应用程序B.但我的要求是在不杀死应用程序B进程的情况下打开F2。在应用B中,frmMain(MDI)是主要的切入点。我怎样才能实现这一目标?
如果无法实现上述目标,那么当我杀死应用程序B时,该应用程序B frmMain - 形成关闭事件应该触发,以便我可以处理某些非常重要的操作。
这是当前代码:
''' <summary>
''' Click handle to open - all buttons need to call this action
''' </summary>
''' <param name="titleArg">Title to be passed to the ScaleApps as Argument </param>
''' <param name="windowTitle">The part of the name for the form as showing in the process title under ctrl+alt+del</param>
''' <remarks></remarks>
Private Sub HandleClick(ByVal titleArg As String, ByVal windowTitle As String)
Dim exeLocation As String = curSettings.ExeLocation
Dim processName As String = "MyApps" 'EXE name. Do not add .EXE
Dim isRunning As Boolean = IsProcessRunning(processName, windowTitle, True)
If Not isRunning Then
isRunning = OpenProcess(exeLocation, processName, titleArg, windowTitle)
End If
BringProcessToFront(processName)
End Sub
#Region "Helper Functions"
<System.Runtime.InteropServices.DllImport("User32.dll")> _
Private Shared Function SetForegroundWindow(handle As IntPtr) As Boolean
End Function
<System.Runtime.InteropServices.DllImport("User32.dll")> _
Private Shared Function ShowWindow(handle As IntPtr, nCmdShow As Integer) As Boolean
End Function
<System.Runtime.InteropServices.DllImport("User32.dll")> _
Private Shared Function IsIconic(handle As IntPtr) As Boolean
End Function
''' <summary>
''' Opens the prossess and passes the specified arguments to it
''' </summary>
''' <param name="exeLocation">EXE full qualified path</param>
''' <param name="processName">The process name without .exe</param>
''' <param name="titleArg">The title Argumemt getting passed to the EXE</param>
''' <param name="windowTitle">The window title showing in processes</param>
''' <returns>True/False</returns>
Private Function OpenProcess(ByVal exeLocation As String, ByVal processName As String, ByVal titleArg As String, ByVal windowTitle As String) As Boolean
Dim isRunning As Boolean = False
Try
If String.IsNullOrEmpty(processName) Then
Message("Process name missing!", zMsgTypes.Err)
Return False
ElseIf String.IsNullOrWhiteSpace(exeLocation) Then
Message("Exe location not specified in the cfg file!", zMsgTypes.Err)
Return False
ElseIf Not File.Exists(exeLocation) Then
Message("Exe location doesn't exist. Please open cfg file and update setting" & vbCrLf & exeLocation, zMsgTypes.Err)
Return False
End If
Dim psi As New ProcessStartInfo
psi.FileName = exeLocation
psi.Arguments = titleArg & " " & curStatus.UserID
psi.UseShellExecute = True
psi.WindowStyle = ProcessWindowStyle.Normal
Dim proc As Process = Process.Start(psi)
'isRunning = IsProcessRunning(processName, windowTitle, False)
isRunning = True
Catch ex As Exception
putHistory("OpenProcess Error:" & ex.Message)
End Try
Return isRunning
End Function
''' <summary>
''' Brings the App to the front
''' </summary>
''' <param name="processName">The process name without .exe</param>
Private Sub BringProcessToFront(ByVal processName As String)
If String.IsNullOrEmpty(processName) Then
Message("Process name missing!", zMsgTypes.Err)
Exit Sub
End If
Try
'here we're going to get a list of all running processes on the computer and then will check out process
Dim pf As Process() = Process.GetProcessesByName(processName)
If pf.Length > 0 Then
Dim handle As IntPtr
For Each procP As Process In pf
'check and bring to the front
handle = procP.MainWindowHandle
If handle <> 0 Then 'Do we have a handle; if only want to being minimized window to front then add IsIconic to the if as well
ShowWindow(handle, 9)
SetForegroundWindow(handle)
End If
Next
End If
Catch ex As Exception
putHistory("BringProcessToFront Error:" & ex.Message)
End Try
End Sub
''' <summary>
''' Checks if the process is running
''' </summary>
''' <param name="processName">The process name without .exe</param>
''' <param name="windowTitle">The window title</param>
''' <param name="isKillProcess">Kill process if the windowTitle is not found</param>
''' <returns>True/False</returns>
Private Function IsProcessRunning(ByVal processName As String, ByVal windowTitle As String, ByVal isKillProcess As Boolean) As Boolean
Try
If String.IsNullOrEmpty(processName) Then
Message("Process name missing!", zMsgTypes.Err)
Return False
ElseIf String.IsNullOrEmpty(windowTitle) Then
Message("Window title missing!", zMsgTypes.Err)
Return False
End If
Dim myTitle As String = ""
For Each pf As Process In Process.GetProcesses()
If pf.ProcessName.ToUpper.StartsWith(processName.ToUpper) Then
myTitle = pf.MainWindowTitle.ToUpper
If Not myTitle.Contains(windowTitle.ToUpper) Then
'Do not kill, find another way to tell the tartget exe to open the new form
'If isKillProcess Then
' pf.Kill()
'End If
'Return False ' do not kill
Return True
End If
If pf.MainWindowTitle.ToUpper.Contains(windowTitle.ToUpper) Then
Return True
End If
End If
Next
Catch ex As Exception
putHistory("IsProcessRunning Error:" & ex.Message)
End Try
Return False
End Function
#End Region
答案 0 :(得分:1)
对应用程序“B”使用Make Single Instance Application功能。您可以传递一个命令行参数来指示应该显示哪个表单。这将触发StartupNextInstance事件,您可以据此采取相应措施。