做一程序,使系统只有一个实例运行,在程序启动时获取是否已有实例运行,代码函数如下:
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
//遍历正在有相同名字运行的例程
foreach (Process process in processes)
{
//忽略现有的例程
if (process.Id != current.Id)
{
//MessageBox.Show(Assembly.GetExecutingAssembly().Location.Replace("/", "\\"));
//确保例程从EXE文件运行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
current.MainModule.FileName)
{
return process;
}
}
}
//没有其它的例程,返回Null
return null;
}
这里如果已经有程序启动的时候,的确能捕获到进程,但由于我把程序最小化时可能在托盘状态,所以程序主窗体的visiable是不可见的false状态,而此时instance.MainWindowHandle得的的值居然是0,instance.MainWindowTitle的值为空,因为程序是多文档窗体,不能确保哪个模块最大化,所以窗体的Caption并不知道,所以也无法用FindWindow的方式去获取主窗体句柄,这时我该如何跟我已启动的程序通信,并让他把窗体显示出来?
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
//遍历正在有相同名字运行的例程
foreach (Process process in processes)
{
//忽略现有的例程
if (process.Id != current.Id)
{
//MessageBox.Show(Assembly.GetExecutingAssembly().Location.Replace("/", "\\"));
//确保例程从EXE文件运行
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
current.MainModule.FileName)
{
return process;
}
}
}
//没有其它的例程,返回Null
return null;
}
这里如果已经有程序启动的时候,的确能捕获到进程,但由于我把程序最小化时可能在托盘状态,所以程序主窗体的visiable是不可见的false状态,而此时instance.MainWindowHandle得的的值居然是0,instance.MainWindowTitle的值为空,因为程序是多文档窗体,不能确保哪个模块最大化,所以窗体的Caption并不知道,所以也无法用FindWindow的方式去获取主窗体句柄,这时我该如何跟我已启动的程序通信,并让他把窗体显示出来?
using System;
using System.Threading;
using System.Windows.Forms;namespace WindowsApplication1
{
static class Program
{
[STAThread]
static void Main()
{
try
{
EventWaitHandle e = EventWaitHandle.OpenExisting("MyActivateEvent");
e.Set(); //已有一个实例运行,通知窗体显示
return;
}
catch
{
// just do nothing if the named event does not exist
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}using System;
using System.Windows.Forms;
using System.Threading;namespace WindowsApplication1
{
public partial class Form1 : Form
{
EventWaitHandle m_ActivateEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "MyActivateEvent");
public Form1()
{
InitializeComponent(); // 分配一个线程用于侦听命名事件
ThreadPool.RegisterWaitForSingleObject(
m_ActivateEvent,
delegate { this.WindowState = FormWindowState.Normal; this.Activate(); }, // restore and activate the window
null,
-1,
false);
}
}
}
关于启动两个同名进程实例碰到的问题,50分请教,关注即有分
With the named event, you cannot. But you can pass a string by: SendMessage (WM_COPYDATA)
命名管道,
共享内存,
Socket,
Remoting,
Database?
我写过一个可以放到任务栏图标的,就是实例化窗体,先把句柄发给另一个程序,然后另一个程序始终向这个句柄发消息的.使用起来没有问题.你试一下.对了,补充一句,这个句柄,我是在实例化以后,Show出来之前就得到的.