打开并重新打开exe文件

时间:2013-04-21 10:12:47

标签: vb.net exe

我试图以这种方式重新打开一个exe文件(我以前打开过): 如果它是打开的,那么不要重新打开它,而只是将该文件带入foucs。如果没有打开,则打开它。 (现在 - 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)

1 个答案:

答案 0 :(得分:1)

如果您拥有要启动的应用程序的代码,那么最好的办法是将该应用程序启动代码更改为不允许同一应用程序的两个实例。 这可以通过这种方式使用Mutex对象来完成

<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    

在此之后,您的其他应用可以启动第一个应用而不进行任何检查,因为在被叫应用中,上面的代码会发现自己的另一个副本并将控件切换到找到的副本。一次运行的同一个应用程序永远不会有两个副本。

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

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

中包含的两个WinAPI声明的类
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

现在在主代码中写下这个

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