winfrom窗体程序怎么保证当前只有一个程序在执行 ??
就是说:打包后点击exe文件执行时,如果该程序已经执行则不再运行新窗体。
我也试用了单件模式 可是不好用啊  要求点击exe文件时当前只运行一个窗体
请高人指教 谢谢了!!

解决方案 »

  1.   


     If   UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName))   <>   0   Then   End   
      

  2.   

    Process   []   localByName   =   Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName) 
      

  3.   

     using   System;   
      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);   
      }   
      }   
      }   
      }   
      
      

  4.   

    刚写了最简单的,把这段替换MAIN方法就好了   
      static   void   Main()     
      {   
      if(System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length>1)   
      {   
      }   
      else   
      {   
      Application.Run(new   MainForm());   
      }   
      }   
      最傻瓜式的
      

  5.   


    这个是进程之间的同步问题。单件模式是在进程内部的机制,在这里没有用。程序运行后,需要在操作系统里面设置一个标记,表示已经有个实例在运行了。当程序再次运行的时候,首先到操作系统里面找这个标记,如果找到了,就说明是第二次运行了,就直接把自己结束掉。如果找不到就正常运行。
    这个可以用互斥体来解决。参看 win32 apiHANDLE CreateMutex( 
    LPSECURITY_ATTRIBUTES lpMutexAttributes, 
    BOOL bInitialOwner, 
    LPCTSTR lpName );
      

  6.   

    exe文件名是可以被人修改成2份的,这个时候就失效了。用操作系统的Mutex是最可靠的。
      

  7.   


      /// <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方法
      

  8.   

     static void Main()
           {           
                try
               {
                   m_MutexObject = new Mutex(false, m_MutexName);
               }
               catch(ApplicationException)
               {            }
               if (!m_MutexObject.WaitOne(0, false))
               {
                   CommFucs.ShowErrMessage(“程序已在运行”); 
                   m_MutexObject.Close();
                   return;
               }
      

  9.   

    程序内部窗体只打开一次,用单件模式
    如果是整个程序只打开一次
    那么在Program类中,启动Form之前加判断,判断当前可执行程序是否正在运行,如果正在运行,则退出此次操作即可。
      

  10.   

    建议使用Mutex核心互斥量,这个是操作系统管理的核心对象。即使修改exe程序运行,该方法也是可靠的。
      

  11.   

            public static void Main()
            {
                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();
                    }
                }
            }
      

  12.   

    System.Threading.Mutex :同步基元,它只向一个线程授予对共享资源的独占访问权。[MSDN]
    实现原理: 在程序启动时,请求一个互斥体,如果能获取对指定互斥的访问权,就继续运行程序,否则就退出程序。
    测试代码: 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,这个怎么理解拥有权?
      

  13.   

    用Mutex。
    根据进程名判断不可取。如果客户机器上同名进程的其他软件已经运行,你的程序就没日没夜了,呵呵。
      

  14.   


    这个问题是没必要考虑的。
    一般发现Mutex Exists以后,不应弹出提示,而是将查找先前窗体并将其前置,然后直接退出。
      

  15.   

      static class Program
        {
            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());
                }
            }
        }
      

  16.   

    哎,csdn怎么老是一些没用的回帖?看着真气人。给你个有用的代码
      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);
                }
            }
        }