做一程序,使系统只有一个实例运行,在程序启动时获取是否已有实例运行,代码函数如下:
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的方式去获取主窗体句柄,这时我该如何跟我已启动的程序通信,并让他把窗体显示出来?

解决方案 »

  1.   

    简单的跨进程通知,可以用“命名事件”来完成: 
    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分请教,关注即有分
      

  2.   


    With the named event, you cannot. But you can pass a string by: SendMessage (WM_COPYDATA)
    命名管道,  
    共享内存,
    Socket,
    Remoting,
    Database?
      

  3.   

    SendMessage 需要有主窗口句柄,我现在获取不到,郁闷,我再考虑考虑
      

  4.   

    主窗口的句柄,可以通过窗口的handle属性(好象是这个名字,忘了,但肯定有一个句柄的属性)来得到,然后,即使不可见,也是可以向其发消息的.
    我写过一个可以放到任务栏图标的,就是实例化窗体,先把句柄发给另一个程序,然后另一个程序始终向这个句柄发消息的.使用起来没有问题.你试一下.对了,补充一句,这个句柄,我是在实例化以后,Show出来之前就得到的.