希望你能提供帮助,我一直在阅读有关互斥的信息,我相信我理解它 - 它应该只限于一个申请流程。
在这个社区的一些指导下,一点谷歌搜索 - 我已经创建了这个简单的代码。
关于应用程序:C#中的简单Windows窗体应用程序
声明Var:
static Mutex mutex = new Mutex(true, "TestAppForm");
在AppForm_Load()上,我有以下代码。
if (!mutex.WaitOne(2000))
{
System.Windows.Forms.Application.Exit();
return;
}
else
{
try
{
// My Code
}
finally
{
mutex.ReleaseMutex();
}
}
我相信我的代码是有效的,因为它仅限于一个应用程序。
但是,我注意到,当打开应用程序然后通过模式退出代码关闭它时,我可以看到它闪烁。
我想要实现的目标::
我想运行该应用程序并检查它是否已经运行 - 如果没有,那么很好,继续前进。 如果应用程序正在运行,我想结束这个过程&然后我想在正在运行的应用程序上设置FOCUS。
谢谢。
==
感谢谷歌搜索后的所有帮助,我发现了这篇文章:
http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
这有助于我实现它。
答案 0 :(得分:0)
AppForm_Load不是您应用程序的第一个入口点。找到创建表单的代码,然后在那里执行。
答案 1 :(得分:0)
请勿检查AppForm_Load
中的互斥锁,而是使用Main
方法检查,如下所示:
private static Mutex _mutex = new Mutex(true, "AppMutex");
static void Main()
{
if(!_mutex.WaitOne(0, true))
{
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new AppForm());
}
答案 2 :(得分:0)
如果要创建单例应用程序,则无法在Mutex
中实现AppForm_Load
逻辑,因为当您到达该点(这不是程序集的entri point / main方法)时,它表示您的应用程序已经启动。通过您的实现,一旦您发现之前创建的另一个实例已经在运行,您就可以最好关闭新实例...为什么不"阻止"直接创建一个新实例?
这是我的单例应用程序模板(Program
类是包含我的应用程序入口点static void Main
的静态类):
#region Using Directives
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
#endregion
namespace MyNamespace
{
public static class Program
{
#region Members: Static
private static Int32 s_MutexMessage;
private static Mutex s_Mutex;
#endregion
#region Properties: Static
public static Int32 MutexMessage
{
get { return s_MutexMessage; }
}
#endregion
#region Methods: Entry Point
[STAThread]
public static void Main()
{
Assembly assembly = Assembly.GetExecutingAssembly();
String assemblyGuid = ((GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;
String mutexName = String.Format(CultureInfo.InvariantCulture, "Local\\{}", assemblyGuid);
s_MutexMessage = NativeMethods.RegisterWindowMessage(assemblyGuid);
Boolean mutexCreated;
s_Mutex = new Mutex(true, mutexName, out mutexCreated);
if (!mutexCreated)
{
NativeMethods.PostMessage((new IntPtr(0xFFFF)), s_MutexMessage, IntPtr.Zero, IntPtr.Zero);
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ApplicationForm());
s_Mutex.ReleaseMutex();
}
#endregion
}
}
然后,在表单类中(在我的示例中为ApplicationForm
):
protected override void WndProc(ref Message m)
{
if (m.Msg == Program.MutexMessage)
{
if (NativeMethods.IsIconic(Handle))
NativeMethods.ShowWindow(Handle, 0x00000009);
NativeMethods.SetForegroundWindow(Handle);
}
base.WndProc(ref m);
}
最后,为了完整起见,以下是我的代码使用的导入,位于NativeMethods
类中(请记住将其标记为internal
,这是一个很好的做法,应该是不容忽视):
internal static class NativeMethods
{
#region Importations
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean IsIconic([In] IntPtr windowHandle);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean PostMessage([In, Optional] IntPtr windowHandle, [In] Int32 message, [In] IntPtr wParameter, [In] IntPtr lParameter);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean SetForegroundWindow([In] IntPtr windowHandle);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean ShowWindow([In] IntPtr windowHandle, [In] Int32 command);
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = false, SetLastError = true)]
internal static extern Int32 RegisterWindowMessage([In] String message);
}
此实现比仅基于Mutex
对象的传统实现略长,需要广泛使用本机互操作,并且必须在项目中的不同类之间进行拆分...但我使用它模板很久很久以前,我可以肯定它是防弹的。