2013-04-21 145 views
1

我想重新打开一个exe文件(我以前打开过): 如果它是打开的,那么不要重新打开它,但只需将该文件变为foucs。如果未打开,请将其打开。 (现在 - exe文件不断重新打开。)打开并重新打开exe文件

任何人都有线索如何做到这一点? (它的工作原理为PowerPoint文件,Word文件,Excel文件,电影文件,PDF文件)

这是我的代码:

Dim file3dopen As New ProcessStartInfo() 
    With file3dopen 
     .FileName = Add3DFolder & cmbx3D.Text 
     .UseShellExecute = True 
     'Minimizes this form and unhides other form 
     Minimize() 
     FormMain.Show() 
     FormMain.TopMost = True 
    End With 
    Process.Start(file3dopen) 
+0

您可以更改要打开的应用程序的源代码吗? – Steve 2013-04-21 10:17:57

+0

你应该调用'file3dopen.Start()',或者在'With'块内部调用'.Start()',根据文档将重用现有的进程,如果它已经被打开。 – 2013-04-21 11:30:23

+0

代码灰色 - 我无法更改要打开的应用程序的源代码。此外,不能使用开始 - 说“开始不是System.Diagnostics.ProcessStartInfo的成员” – 2013-04-22 20:32:25

回答

1

如果您拥有的是要启动应用程序的代码,则最好的办法是更改该应用程序启动代码,以便不允许同一应用程序的两个实例。 这可以通过使用互斥对象以这种方式

<DllImport("user32.dll")> _ 
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean 
End Function 

<STAThread()> _ 
Shared Sub Main() 
    Dim createdNew As Boolean = true; 
    Using mutes = new Mutex(true, "MyApplicationName", createdNew) 
     if createdNew Then 
      Application.EnableVisualStyles() 
      Application.SetCompatibleTextRenderingDefault(false) 
      Application.Run(new MainForm()) 
     else 
      Dim current = Process.GetCurrentProcess(); 
      for each process in Process.GetProcessesByName(current.ProcessName) 
       if process.Id <> current.Id Then 
        SetForegroundWindow(process.MainWindowHandle) 
        Exit For 
       End If 
      Next 
     End If 
    End Using  

在此之后进行,你的其他应用程序可以推出的第一款应用,而无需任何检查,因为在名为app上面的代码中发现自己的另一个副本和开关控制到找到的副本。永远不会有同一个应用程序同时运行的两个副本。

而是,如果您不拥有要启动的应用程序,那么您只能在代码上工作,添加测试以查看应用程序进程名是否存在于当前正在运行的进程列表中 例如:

Private Sub TestIfRunningIE 
    if IsApplicationRunning("IEXPLORE") Then 
     Console.WriteLine("Internet Explorer is running") 
    Else 
     Console.WriteLine("Internet Explorer is NOT running") 
    End If 
End Sub 


Public Function IsApplicationRunning(ByVal appName As String) As Boolean 
    For Each aProcess in Process.GetProcesses() 
     If aProcess.ProcessName.StartsWith(appName, StringComparisong.CurrentCultureIgnoreCase) Then 
      Return true 
     End If 
    Next 
    Return False 
End Function 

当然,这都需要你知道进程的名字,但你可以很容易地找到使用可用的无数自由的过程工具的一个名字。

编辑 为了将发现,我们需要一点从WinAPI的帮助前台的过程。 首先,改变IsApplicationRunning返回过程中发现

Public Function IsApplicationRunning(ByVal appName As String) As Process 
    For Each aProcess in Process.GetProcesses() 
     If aProcess.ProcessName.StartsWith(appName, StringComparisong.CurrentCultureIgnoreCase) Then 
      Return aProcess 
     End If 
    Next 
    Return Nothing 
End Function 

然后构建一个包含有对user32.dll

Public Class Win32Helper 
    <System.Runtime.InteropServices.DllImport("user32.dll", _ 
    EntryPoint:="SetForegroundWindow", _ 
    CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _ 
    CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _ 
    Public Shared Function _ 
    SetForegroundWindow(ByVal handle As IntPtr) As Boolean 
    End Function 

    <System.Runtime.InteropServices.DllImport("user32.dll", _ 
    EntryPoint:="ShowWindow", _ 
    CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _ 
    CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _ 
    Public Shared Function ShowWindow(ByVal handle As IntPtr, ByVal nCmd As Int32) As Boolean 
    End Function 
End Class 

2个WinAPI的声明,现在在你的主代码写这个

Dim proc = IsApplicationRunning("your_process_name") 
if proc isnot Nothing then 
    Dim handle As IntPtr = proc.MainWindowHandle 
    Dim Win32Help As New Win32Helper 
    If Not IntPtr.Zero.Equals(handle) Then 
     Win32Helper.ShowWindow(handle, 1) 
     Win32Helper.SetForegroundWindow(handle) 
    End If 
else 
    Console.WriteLine("Process not found") 
End if 

作为参考,我找到了实现Win32Helper类的代码here

+0

我使用VS 2010和.NET Framework 3.5(不能更高)和“IsApplicationRunning”和“console.writeline “给我错误 - 这是在C#中吗?你知道VB.net中的等价物吗? – 2013-04-22 23:23:56

+0

什么错误?请给出错误信息。 Console.WriteLine只是调试控制台上的一个输出消息,当然函数应该在类内 – Steve 2013-04-23 06:59:34

+0

错误=“IsApplicationRunning未声明” - 知道了 - 我必须在测试前放置函数: - (( – 2013-04-23 22:57:34