winfrom窗体程序怎么保证当前只有一个程序在执行 ??
就是说:打包后点击exe文件执行时,如果该程序已经执行则不再运行新窗体。
我也试用了单件模式 可是不好用啊 要求点击exe文件时当前只运行一个窗体
请高人指教 谢谢了!!
就是说:打包后点击exe文件执行时,如果该程序已经执行则不再运行新窗体。
我也试用了单件模式 可是不好用啊 要求点击exe文件时当前只运行一个窗体
请高人指教 谢谢了!!
解决方案 »
- +=
- 软件打包问题
- comboBox1 如何读取数据库数据 然后显示在下拉框里面 请大大帮忙
- 在C#中用何种数据结构存储treeview?
- c# 使用FileStream读取大于计算机内存文件的解决办法
- 加密问题:怎样用dotFramework类库进行加密,我要把用XML做数据库的信息加密,最好有C#代码.
- WinForm抓取网页数据的问题
- vs2008 水晶报表传值的问题!!!!谢谢各位大侠!
- C#怎样写DLL文件VB可以调用?(急急急急急急急急急急急急急急急!!!!!!!!!!!!!!!!!!!!!!!)
- 关于ie浏览器问题?
- 一个remoting的很简单很简单的问题
- 大家来看一下吧,关于去除HTML标记语言的问题
If UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) <> 0 Then End
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.InteropServices;
namespace Example104_使程序只能够运行一个
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(272, 189);
this.Name = "Form1";
this.Text = "Form1";
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[StructLayout( LayoutKind.Sequential)]
public class SECURITY_ATTRIBUTES
{
public int nLength;
public int lpSecurityDescriptor;
public int bInheritHandle;
}
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int GetLastError();
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern IntPtr CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes,bool bInitialOwner,string lpName);
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int ReleaseMutex(IntPtr hMutex);
const int ERROR_ALREADY_EXISTS = 0183;
[STAThread]
static void Main()
{
IntPtr hMutex;
hMutex=CreateMutex(null,false,"test");
if (GetLastError()!=ERROR_ALREADY_EXISTS)
{
Application.Run(new Form1());
}
else
{
MessageBox.Show("本程序只允许同时运行一个");
ReleaseMutex(hMutex);
}
}
}
}
static void Main()
{
if(System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length>1)
{
}
else
{
Application.Run(new MainForm());
}
}
最傻瓜式的
这个是进程之间的同步问题。单件模式是在进程内部的机制,在这里没有用。程序运行后,需要在操作系统里面设置一个标记,表示已经有个实例在运行了。当程序再次运行的时候,首先到操作系统里面找这个标记,如果找到了,就说明是第二次运行了,就直接把自己结束掉。如果找不到就正常运行。
这个可以用互斥体来解决。参看 win32 apiHANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName );
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length == 1)
{ Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("程序已在运行!");
Application.Exit();
}
}修改Program.cs的MAIN方法
{
try
{
m_MutexObject = new Mutex(false, m_MutexName);
}
catch(ApplicationException)
{ }
if (!m_MutexObject.WaitOne(0, false))
{
CommFucs.ShowErrMessage(“程序已在运行”);
m_MutexObject.Close();
return;
}
如果是整个程序只打开一次
那么在Program类中,启动Form之前加判断,判断当前可执行程序是否正在运行,如果正在运行,则退出此次操作即可。
{
bool ownsMutex;
using (Mutex mutex = new Mutex(true, "MutexExample", out ownsMutex))
{
if (ownsMutex)
{
Console.ReadLine();
mutex.ReleaseMutex();
}
else
{
Console.WriteLine("Another instance of this application " +
" already owns the mutex named MutexExample.");
Console.ReadLine();
}
}
}
实现原理: 在程序启动时,请求一个互斥体,如果能获取对指定互斥的访问权,就继续运行程序,否则就退出程序。
测试代码: class Test
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
bool flag=false;
System.Threading.Mutex mutex=new System.Threading.Mutex(true,"Test",out flag);
//第一个参数:true--给调用线程赋予互斥体的初始所属权
//第一个参数:互斥体的名称
//第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true
if(flag)
{
Console.Write("Running");
mutex.ReleaseMutex();
}
else
{
Console.Write("Another is Running");
System.Threading.Thread.Sleep(5000);//线程挂起5秒钟
Environment.Exit(1);//退出程序
}
Console.ReadLine();
}问题出来了。。如果第一次运行,输出"Running"。
不关闭第一次运行的程序, 进行第二次运行,输出"Another is Running",当关闭第一个后再次运行第三个,第二个没有获得mutex的拥有权,是否应该显示running呢? 经过测试,依然显示Another is Running,这个怎么理解拥有权?
根据进程名判断不可取。如果客户机器上同名进程的其他软件已经运行,你的程序就没日没夜了,呵呵。
这个问题是没必要考虑的。
一般发现Mutex Exists以后,不应弹出提示,而是将查找先前窗体并将其前置,然后直接退出。
{
private static Mutex mutex;
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
mutex = new Mutex(true, "名字");
//保证只有一个实例运行
if (mutex.WaitOne(0, false))
{
Application.Run(new Form1());
}
}
}
static class Program
{
private const int WS_SHOWMAX = 3;
public const Int32 AW_BLEND = 0x00080000;
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] InputStrs)
{
Process instance = GetRunningInstance();
if (instance == null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
else
{
HandleRunningInstance(instance);
}
}
public static Process GetRunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName); foreach (Process process in processes)
{
if (process.Id != current.Id)
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
return process;
}
return null;
} public static void HandleRunningInstance(Process instance)
{
if (instance.MainWindowHandle.ToInt32() != 0)
{
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWMAX);
SetForegroundWindow(instance.MainWindowHandle);
}
else
{
IntPtr hwnd = FindWindow("FormMain.cs", "FormMain");
if (hwnd.ToInt32() == 0)
{
hwnd = FindWindow("FormMain.cs", "FormMain");
if (hwnd.ToInt32() == 0)
hwnd = FindWindow(null, "FormMain");
//AnimateWindow(hwnd, 1000, AW_BLEND);
}
ShowWindowAsync(hwnd, WS_SHOWMAX);
SetForegroundWindow(hwnd);
}
}
}