仿迅雷的功能,当程序关闭,缩小在右下时,用户再去运行程序,原窗体显示出来,而新窗体会自动退出。我的代码如下,差一点就成功了,现在的效果是登录窗体会不停的闪,只有右击右下方的图标,退出程序后,才会再出一个新窗体,有哪位高手指点下,要怎么写呀?
                       //检查进程是否已经启动,已经启动则显示报错信息退出程序。 
            if (System.Diagnostics.Process.GetProcessesByName("IT部门管理系统").Length > 1)
            {                Thread logTread = Thread.CurrentThread;
                Process p = Process.GetCurrentProcess();
                //Thread t = new Thread(new ThreadStart(delegate { Application.Run(new frm_main()); }));  //用线程关闭登录窗体   要先using System.Threading;  //线程
                //t.SetApartmentState(ApartmentState.STA);
                Process.Start("IT部门管理系统");  //运行进程               
                p.Kill();           //杀掉当前线程       
                logTread.Abort();
                this.Dispose();
                Application.Exit();
                //MessageBox.Show("程序已运行,请点击右下方图标!");
                               
            }
            else
            {

解决方案 »

  1.   

    不是这样
    static class Program
    {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool createdNew;   //第三个参数用于返回特定名称的互斥锁定是否存在
                Mutex mutex = new Mutex(false, "ProCharpMutex", out createdNew);
                if (!createdNew) {
                    MessageBox.Show("An instance has already runned!"); //可以进行激活和显示的操作
                    Application.Exit();
                    return;
                }
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    用mutex判断,如果一个同一个程序打开过,就禁止第二再打开,可以加上让第一个显示出来
      

  2.   

        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool bResult;
                System.Threading.Mutex mutex = new System.Threading.Mutex(true, "425D04", out bResult);
                if (!bResult)
                {
                    IntPtr hHandle = OpenFileMapping(FILE_MAP_READ, 0, "05A79C");
                    IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_READ, 0, 0, 0);
                    IntPtr hWnd = new IntPtr(Marshal.ReadInt32(lpAddress));
                    ShowWindow(hWnd, SW_SHOWNORMAL);
                    SetForegroundWindow(hWnd);
                }
                else
                {                Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Form1 frm = new Form1();                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
                    sa.nLength = 12;
                    sa.lpSecurityDescriptor = 0;
                    sa.bInheritHandle = 1;                IntPtr hHandle = CreateFileMapping(-1, ref sa, PAGE_READWRITE, 0, 4, "05A79C");
                    IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_WRITE, 0, 0, 0);
                    Marshal.WriteInt32(lpAddress, frm.Handle.ToInt32());
                    Application.Run(frm);
                    CloseHandle(hHandle);
                }
            }
            [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
            private extern static IntPtr CreateFileMapping(Int32 hFile,
                                                ref SECURITY_ATTRIBUTES lpFileMappingAttributes,
                                                Int32 flProtect, Int32 dwMaximumSizeHigh,
                                                Int32 dwMaximumSizeLow,
                                                string lpName);
            [DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
            private extern static IntPtr OpenFileMapping(Int32 dwDesiredAccess, Int32 bInheritHandle, string lpName);        [DllImport("Kernel32.dll")]
            private extern static IntPtr MapViewOfFile(IntPtr hFileMappingObject, Int32 dwDesiredAccess,
                                                Int32 dwFileOffsetHigh,
                                                Int32 dwFileOffsetLow,
                                                Int32 dwNumberOfBytesToMap);
            [DllImport("kernel32.dll")]
            private extern static bool CloseHandle(IntPtr hHandle);
            [DllImport("User32.dll")]
            private extern static bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
            [DllImport("user32.dll")]
            public static extern int SetForegroundWindow(IntPtr hwnd);
            private const Int32 PAGE_READWRITE = 0x04;
            private const Int32 FILE_MAP_WRITE = 0x02;
            private const Int32 FILE_MAP_READ = 0x04;
            private const Int32 SW_SHOWNORMAL = 0x01;    }
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public Int32 nLength;
            public Int32 lpSecurityDescriptor;
            public Int32 bInheritHandle;
        }
      

  3.   

    我用了以下两种方法,可就是程序不会自动弹出,还是缩小在右下方,只是没有多出图标出来,达不到效果。哪位有高招的,请指教一下呀。先讲实现方法:   
      首先依然是命名空间:   
              using   System.Threading;   
      然后修改   
      static   void   Main()     
          {   
            bool   bCreatedNew;   
        
            Mutex   ltt   =new   Mutex(   false,   "myUniqueName",   out   bCreatedNew   );   
        
            if(   bCreatedNew   )   
        
                      Application.Run(new   Form1());   
          }   
      接下来,说一下原理:   
      当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex   是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。   
      相信如果学过操作系统的朋友一定能够看的懂.   
      可以使用   WaitHandle.WaitOne   请求互斥体的所属权。拥有互斥体的线程可以在对   Wait   的重复调用中请求相同的互斥体而不会阻塞其执行。但线程必须调用   ReleaseMutex   方法同样多的次数以释放互斥体的所属权。如果线程在拥有互斥体期间正常终止,则互斥体状态设置为终止,并且下一个等待线程获得所属权。如果没有线程拥有互斥体,则互斥体状态为终止。方法一:使用Mutex来进行
        1. 首先要添加如下的namespace:
           using System.Threading;
    2. 修改系统Main函数,大致如下:
                    bool bCreatedNew;
                    //Create a new mutex using specific mutex name
                    Mutex m =new Mutex( false, "myUniqueName", out bCreatedNew );
                   if( bCreatedNew )
                   Application.Run(new yourFormName());
    如上面编码就可以了,要注意的一点是,在给Mutex起名字的时候,不要太简单,以防止和其他程序的Mutex重复,从而达不到所预想的效果。
    方法二:使用Process来进行
    1. 首先要添加如下的namespace:
    using System.Diagnostics;
    using System.Reflection;
    2. 添加如下函数:
            public static Process RunningInstance() 
            { 
                Process current = Process.GetCurrentProcess(); 
                Process[] processes = Process.GetProcessesByName(current.ProcessName); 
                //Loop through the running processes in with the same name 
                foreach (Process process in processes) 
                { 
                    //Ignore the current process 
                    if (process.Id != current.Id) 
                    { 
                        //Make sure that the process is running from the exe file. 
                        if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName) 
                        { 
                            //Return the other process instance. 
                            return process; 
                        } 
                    } 
                } 
                //No other instance was found, return null. 
                return null; 
            } 
    3. 修改系统Main函数,大致如下:
                if( RunningInstance() == null )
                    Application.Run(new yourFormName());
    如上面编码就可以了,要注意的一点是,在判断进程模块文件名是否相等这部分的代码,是可选的。如果当前的程序在文件系统中只存在一个的话,以上的方法是可以的;否则不要删除这部分的代码。
    对比两种方法,就效率和简便性来说,前一种方法是最好的,也是我比较喜欢的;后一种方法,速度比较慢,其次通过ProcessName去系统中查寻,有可能查出来的Process并不是我想要得,虽说在后面加了文件目录判断,但是其含有潜在的问题(前面已经说出来)。不过,第一种方法也有缺陷,就是扩展性操作不方便,例如:让程序只运行一次,如果程序已经运行,把它弹出并显示到最前面。对于此,后一种方法就很有优势了。