前言 在開發應用程式時,通常只讓程式運行一個實例。所以,就要判斷程式是否已經運行。 下麵是我自己在項目中使用到,封裝好的幫助類。有 普通的 C 應用程式 和 Windows CE 和 Windows Mobile 應用程式使用的方法。 主要是通過 System.Threading.Mutex 類 和 ...
前言
在開發應用程式時,通常只讓程式運行一個實例。所以,就要判斷程式是否已經運行。
下麵是我自己在項目中使用到,封裝好的幫助類。有 普通的 C# 應用程式 和 Windows CE 和 Windows Mobile 應用程式使用的方法。
主要是通過 System.Threading.Mutex 類 和 Win32 API 來實現,下麵就是各自的代碼,調用示例在最後面。
普通 C# 應用程式
主要是 Windows 窗體應用程式和控制台程式。
1. 使用 System.Threading.Mutex 類
using System.Threading;
namespace XY.Util.Helper
{
/// <summary>
/// Mutex helper
/// </summary>
public class MutexHelper
{
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assembly">程式集實例</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
{
string strAppName = assembly.GetName().Name;
return IsApplicationOnRun(strAppName);
}
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assemblyName">程式名稱</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(string assemblyName)
{
bool ret = false;
//第一個參數:true--給調用線程賦予互斥體的初始所屬權
//第一個參數:互斥體的名稱
//第三個參數:返回值,如果調用線程已被授予互斥體的初始所屬權,則返回true
Mutex mutex = new Mutex(true, assemblyName, out ret);
return !ret;
}
}
}
2. 使用 Win32 API
using System;
using System.Runtime.InteropServices;
namespace XY.Util.Helper
{
/// <summary>
/// Mutex helper
/// </summary>
public class MutexHelper
{
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr OpenMutex(uint dwDesiredAccess, bool bInitialOwner, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assembly">程式集實例</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
{
string strAppName = assembly.GetName().Name;
return IsApplicationOnRun(strAppName);
}
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assemblyName">程式名稱</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(string assemblyName)
{
bool ret = false;
if (OpenMutex(0x1F0001, false, assemblyName) == IntPtr.Zero)
{
CreateMutex(IntPtr.Zero, false, assemblyName);
ret = true;
}
return ret;
}
}
}
Windows CE | Windows Mobile 應用程式
在 Windows CE 和 Windows Mobile 中實現,是通過 Win32 API實現的,下麵是封裝的幫助類:
參考:
using System;
using System.Runtime.InteropServices;
namespace XY.Util.Helper
{
/// <summary>
/// Mutex helper
/// </summary>
public class MutexHelper
{
[DllImport("coredll.dll", EntryPoint = "CreateMutex", SetLastError = true)]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);
[DllImport("coredll.dll", EntryPoint = "ReleaseMutex", SetLastError = true)]
public static extern bool ReleaseMutex(IntPtr hMutex);
private const int ERROR_ALREADY_EXISTS = 0183;
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assembly">程式集實例</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(System.Reflection.Assembly assembly)
{
string strAppName = assembly.GetName().Name;
return IsApplicationOnRun(strAppName);
}
/// <summary>
/// 判斷程式是否已經運行
/// <param name="assemblyName">程式名稱</param>
/// </summary>
/// <returns>
/// true: 程式已運行
/// false: 程式未運行
/// </returns>
public static bool IsApplicationOnRun(string assemblyName)
{
IntPtr hMutex = CreateMutex(IntPtr.Zero, true, assemblyName);
if (hMutex == IntPtr.Zero)
{
throw new ApplicationException("Failure creating mutex: " + Marshal.GetLastWin32Error().ToString("X"));
}
if (Marshal.GetLastWin32Error() == ERROR_ALREADY_EXISTS)
{
ReleaseMutex(hMutex);
return true;
}
return false;
}
}
}
示例代碼
調用示例:
using System;
using System.Reflection;
using XY.Util.Helper;
namespace MutexTest
{
static class Program
{
[MTAThread]
static void Main(string[] args)
{
bool run;
//方式一
run = MutexHelper.IsApplicationOnRun("ApplicationName");
//方式二
run = MutexHelper.IsApplicationOnRun(Assembly.GetExecutingAssembly());
if (run)
{
// application is running...
// Exit.
}
else
{
// start application ...
// startup...
}
}
}
}