防止.NET應(yīng)用多實(shí)例運(yùn)行的有效方法
核心思路
1、檢查是否已有程序?qū)嵗\(yùn)行
使用 System.Diagnostics.Process 獲取當(dāng)前程序進(jìn)程,并與系統(tǒng)中所有同名的程序進(jìn)程進(jìn)行比較。如果發(fā)現(xiàn)另一個(gè)同名進(jìn)程,則認(rèn)為程序已經(jīng)運(yùn)行。
2、激活已運(yùn)行的程序窗口
如果發(fā)現(xiàn)已有實(shí)例運(yùn)行,使用 Win32 API 操作將其窗口置于前臺,避免用戶啟動多個(gè)實(shí)例。
3、運(yùn)行主程序邏輯
如果沒有其他實(shí)例運(yùn)行,正常啟動主程序。
代碼解析
1、檢查是否已有程序運(yùn)行
以下代碼通過進(jìn)程名稱篩選當(dāng)前運(yùn)行的程序進(jìn)程列表,返回除當(dāng)前進(jìn)程外的其他同名進(jìn)程(如果存在):
public static Process GetExistProcess()
{
Process currentProcess = Process.GetCurrentProcess(); // 當(dāng)前程序
foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
{
if (process.Id != currentProcess.Id) // 找到其他同名進(jìn)程
{
return process; // 返回已運(yùn)行的進(jìn)程
}
}
return null; // 沒有其他實(shí)例
}
2、主程序入口
在 Main 方法中調(diào)用 GetExistProcess 檢查程序?qū)嵗?/p>
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var runningProcess = GetExistProcess();
if (runningProcess != null) // 如果有實(shí)例運(yùn)行
{
IntPtr mainWindowHandle = runningProcess.MainWindowHandle;
if (mainWindowHandle == IntPtr.Zero) // 窗口被隱藏
{
mainWindowHandle = FindWindow(null, "唯一程序");
}
ShowWindowAsync(mainWindowHandle, 1); // 顯示窗口
SetForegroundWindow(mainWindowHandle); // 置于前臺
}
else
{
Application.Run(new MainForm()); // 啟動新實(shí)例
}
}
}
3、Win32 API 調(diào)用
以下是關(guān)鍵的 Win32 API 函數(shù),用于操作窗口顯示和前臺設(shè)置:
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll ")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
FindWindow: 根據(jù)窗口名稱查找窗口句柄。
ShowWindowAsync: 顯示或隱藏窗口。
SetForegroundWindow: 將窗口設(shè)置為前臺窗口。
注意事項(xiàng)
1、窗口名稱匹配問題
如果窗口標(biāo)題動態(tài)變化,FindWindow 的效果可能不佳,需保證窗口標(biāo)題唯一或改用其他識別方法。 2、權(quán)限問題
如果以管理員權(quán)限運(yùn)行程序,SetForegroundWindow 操作可能會被限制。需要確保權(quán)限一致。
3、多線程問題
如果程序使用了多線程,需注意線程間的窗口操作同步。
優(yōu)化建議
1、使用互斥量
利用 Mutex 可以更簡潔地實(shí)現(xiàn)程序唯一性。例如:
static Mutex mutex = new Mutex(true, "UniqueAppName", out bool createdNew);
if (!createdNew)
{
// 已經(jīng)有實(shí)例運(yùn)行
return;
}
2、窗口句柄緩存
可以在程序啟動時(shí)緩存主窗口句柄,避免頻繁調(diào)用 FindWindow。
3、日志記錄
在實(shí)際應(yīng)用中建議記錄重復(fù)啟動的嘗試,以便后續(xù)調(diào)試和優(yōu)化。
總結(jié)
這是一種基于進(jìn)程和 Win32 API 的方法來保持程序唯一性的解決方案。代碼邏輯清晰,適用于大多數(shù)桌面應(yīng)用場景。如果你有更復(fù)雜的需求或更高的性能要求,建議結(jié)合互斥量或現(xiàn)代框架特性來實(shí)現(xiàn)更可靠的方案。
最后
到此這篇關(guān)于防止.NET應(yīng)用多實(shí)例運(yùn)行的有效方法的文章就介紹到這了,更多相關(guān)防止.NET多實(shí)例運(yùn)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Fiddler調(diào)試visual studion多個(gè)虛擬站點(diǎn)的問題分析
本篇文章小編為大家介紹,使用Fiddler調(diào)試visual studion多個(gè)虛擬站點(diǎn)的問題分析。需要的朋友參考下2013-04-04
Web系統(tǒng)通過EXE文件實(shí)現(xiàn)讀取客戶電腦MAC等硬件信息且兼容非IE瀏覽器
我們在實(shí)際Web應(yīng)用中,可能會遇到“需要限定特定的電腦或用戶才能使用系統(tǒng)”的問題。2014-08-08
MVC+EasyUI+三層架構(gòu)簡單權(quán)限管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了MVC+EasyUI+三層架構(gòu)簡單權(quán)限管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
Repeater的FooterTemplate顯示某列總計(jì)思路與代碼
在Repeater的FooterTemplate顯示某列總計(jì),接下來與大家分享詳細(xì)的實(shí)現(xiàn)方案,感興趣的各位可以參考下哈2013-03-03
推薦8項(xiàng)提高 ASP.NET Web API 性能的技術(shù)
ASP.NET Web API 是非常棒的技術(shù)。編寫 Web API 十分容易,以致于很多開發(fā)者沒有在應(yīng)用程序結(jié)構(gòu)設(shè)計(jì)上花時(shí)間來獲得很好的執(zhí)行性能。2014-08-08
Repeater事件OnItemCommand取得行內(nèi)控件的方法
這篇文章主要介紹了Repeater事件OnItemCommand取得行內(nèi)控件的方法,有需要的朋友可以參考一下2014-01-01

