很多時候,我們開發的程序,需要單例運行的的功能,即整個應用程序只允許同時運行最多一個實例,重復運行的時候,激活當前實力,顯示其界面。
在C#程序中,其解決方案有多重,可以參照Charles Chen 的C#程序只允許運行一個實例的解決方案一文。
參照其文章,我決定使用調用Windows Api的方法,大致如下:
namespace BarCodeSystem
{
public static class Program
{
///
/// Application Entry Point.
///
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute(PresentationBuildTasks, 4.0.0.0)]
public static void Main()
{
Process instance = RunningInstance();
if (instance == null)
{
BarCodeSystem.App app = new BarCodeSystem.App();
app.InitializeComponent();
app.Run();
}
else
{
HandleRunningInstance(instance);
}
}
///
/// 獲取進程
///
///
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
if (process.Id != current.Id)
{
if (process.MainModule.FileName == current.MainModule.FileName)
{
return process;
}
}
}
return null;
}
///
/// 處理進程
///
///
public static void HandleRunningInstance(Process instance)
{
MyProcess mp = new MyProcess();
IntPtr x = mp.GetMainWindowHandle(instance.Id);
Application.EnableVisualStyles();
//確保窗體不是最大化或者最小化
ShowWindowAsync(x, WS_SHOWNORMAL);
//將實例放置到前台
SetForegroundWindow(instance.MainWindowHandle);
}
///
/// 該函數設置由不同線程產生的窗口的顯示狀態
///
///窗口句柄
///指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數的說明部分
/// 如果函數原來可見,返回值為非零;如果函數原來被隱藏,返回值為零
[DllImport(User32.dll)]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
///
/// 該函數將創建指定窗口的線程設置到前台,並且激活該窗口。鍵盤輸入轉向該窗口,並為用戶改各種可視的記號。
/// 系統給創建前台窗口的線程分配的權限稍高於其他線程。
///
///將被激活並被調入前台的窗口句柄
/// 如果窗口設入了前台,返回值為非零;如果窗口未被設入前台,返回值為零
[DllImport(User32.dll)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
這裡,我自定義了Main函數,當然,也可以在項目中本來的Main函數中添加代碼,達到相同的效果。