2013-04-21 181 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