如何用c#程序实现:当启动一个程序时,如果该程序的一个进程已在运行中,弹出正在运行中的进程的主窗口,不再启动新的进程? 
请给出完整的代码,越详细越好!谢谢!

解决方案 »

  1.   

    参考下
    http://hi.baidu.com/hetaoos/blog/item/2abda7185ab63a0334fa415f.html
    http://www.builder.com.cn/2007/0907/495324.shtml
    http://www.cnblogs.com/wequst/archive/2009/01/08/1371754.html
      

  2.   

    我使用的是下面这个查找进程的方法
    不知道还有没有更好用的方法Public Function RunningInstance() As Process
            'On Error Resume Next(修改注册表项目 HKLM\SYSTEM\CuttentControlSet\Services\Perfproc\Performance\Disable Perforance Counters=0)
            Dim current As Process        Try
                current = Process.GetCurrentProcess
                Dim processes As Process() = Process.GetProcessesByName(current.ProcessName)            '查找相同名的进程 
                Dim tmpProcess As Process
                For Each tmpProcess In processes
                    '忽略当前进程 
                    If tmpProcess.Id <> current.Id Then
                        '确认相同名的进程运行位置是否相同 
                        If Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", "\") = current.MainModule.FileName Then
                            '返回其它的运行实例 
                            Return tmpProcess
                        End If
                    End If
                Next tmpProcess
                '没有其它实例,返加空值 
                Return Nothing
            Catch ex As Exception
                
            Finally        End Try    End Function
      

  3.   


    //获取指定的进程名
    System.Diagnostics.Process[] prProcesses =
                    System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
    //如果获取的进程名多于一个(本身也有一个嘛~)
    if (prProcesses.Length > 1)[code=C#]
    {
             MessageBox.Show("已启动过了一个实例!");//这句话可以换成弹出原窗口的代码。
             //退出
             return;
    }
    [/code]
     
    源:
    http://hi.baidu.com/genger/blog/item/09ac8c82f2b5ef97f703a613.html
      

  4.   

    //获取指定的进程名
    System.Diagnostics.Process[] prProcesses =
                    System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
    //如果获取的进程名多于一个(本身也有一个嘛~)
    if (prProcesses.Length > 1)

            MessageBox.Show("已启动过了一个实例!");//这句话可以换成弹出原窗口的代码。 
            //退出 
            return; 
      

  5.   

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Threading;namespace FallingGold
    {
        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());
                }
            }
        }
    }
      

  6.   


    [STAThread]
    public static void Main()
    {
        bool ret;
        System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out ret);
        if (ret)
        {
            System.Windows.Forms.Application.EnableVisualStyles();   //这两行实现   XP   可视风格   
            System.Windows.Forms.Application.DoEvents();
            System.Windows.Forms.Application.Run(new Main());
            //   Main   为你程序的主窗体,如果是控制台程序不用这句   
            mutex.ReleaseMutex();
        }
        else
        {
            MessageBox.Show(null, "有一个和本程序相同的应用程序已经在运行,请不要同时运行多个本程序。\n\n这个程序即将退出。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //   提示信息,可以删除。   
            Application.Exit();//退出程序   
        }
    }
      

  7.   

    关键是这个:弹出正在运行中的进程的主窗口这个要用到API,有做过,代码丢失了!
      

  8.   

    [c#code][STAThread]
    public static void Main()
    {
        bool ret;
        System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out ret);
        if (ret)
        {
            System.Windows.Forms.Application.EnableVisualStyles();   //这两行实现   XP   可视风格   
            System.Windows.Forms.Application.DoEvents();
            System.Windows.Forms.Application.Run(new Main());
            //   Main   为你程序的主窗体,如果是控制台程序不用这句   
            mutex.ReleaseMutex();
        }
        else
        {
            MessageBox.Show(null, "有一个和本程序相同的应用程序已经在运行,请不要同时运行多个本程序。\n\n这个程序即将退出。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //   提示信息,可以删除。   
            Application.Exit();//退出程序   
        }
    }
    [/code]
      

  9.   

    int AddNum    = 0;
    //监听线程名称
    string PName = @"DataBaseExecute";
    //获得本机所有进程
    Process[] myProcess = Process.GetProcesses(); if(myProcess != null)
    {
    foreach(Process Everypro in myProcess)
    {
    //执行进程存在时
    if(PName.ToLower() == Everypro.ProcessName.ToLower())
    {
    AddNum = ++AddNum;

    }
    }
    }
    if(AddNum > 1)
    {
    MessageBox.Show("此程序已经启动,本次操作将终止","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);
    this.myNotifyIcon.Visible = false;
    this.Close();
    this.Dispose();
    Application.Exit();
    }
      

  10.   

    VB中只要:Sub Main()
        If App.PrevInstance Then
            MSG "业务系统已经在运行!"
            End
        End If
    End Sub
      

  11.   

    我们时常会看到某些软件有这样的功能.
    当程序已经运行的时候再运行这个程序程序会把以前运行的主界面显示在前台来.下面代码就是这个功能.
    VERSION 5.00
    Begin VB.Form frmMain 
       Caption         =   "李小俊是个猪头"
       ClientHeight    =   3195
       ClientLeft      =   60
       ClientTop       =   345
       ClientWidth     =   4680
       LinkTopic       =   "Form1"
       ScaleHeight     =   3195
       ScaleWidth      =   4680
       StartUpPosition =   3  '窗口缺省
    End
    Attribute VB_Name = "frmMain"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Private Const WM_SYSCOMMAND = &H112
    Private Const SC_RESTORE = &HF120&Private Sub Form_Load()
        Me.WindowState = 1
        If App.PrevInstance Then
            Me.Caption = ""
            Dim hWnd As Long
            hWnd = FindWindow(vbNullString, "李小俊是个猪头")
            If hWnd > 0 Then
                SendMessage hWnd, WM_SYSCOMMAND, SC_RESTORE, 0
                SetForegroundWindow hWnd
                Unload Me: End
            End If
        End If
    End Sub 
      

  12.   

    我上面的是转载,里面部分文字不是骂人的http://topic.csdn.net/t/20040118/14/2674434.html
      

  13.   

    [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                mutex = new Mutex(true, "一个");            
                //保证只有一个实例运行
                if (mutex.WaitOne(0, false))
                {
                    Application.Run(new Form1());
                }
            }
      

  14.   

    凡是使用静态变量思想的都是错的【6楼就是典型的这种思想】
    你重新开启一个程序,你的静态变量还不是要重新初始化?
    这个实现起来很简单,判断以下进程就可以了,当然,还要加上对程序运行位置的判断,不能仅仅判断进程的名称
    【ps:代码网上一大堆,MSDN也有】
      

  15.   

      [DllImport("user32.dll")]
            private static extern bool ShowWindow(IntPtr hWnd, long nCmdShow);        [DllImport("user32.dll")]
            private static extern bool SetForegroundWindow(IntPtr hWnd);static bool HasRun()
            {
                Process currentProcess = Process.GetCurrentProcess();
                Process[] myProcess = Process.GetProcessesByName("APP");
                if (myProcess.Length > 1)
                {
                    for (int i = 0; i < myProcess.Length; i++)
                    {
                        if (currentProcess.Id != myProcess[i].Id)
                        {
                            SetForegroundWindow(myProcess[i].MainWindowHandle);
                            myProcess[i].StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                            ShowWindow(myProcess[i].MainWindowHandle, 1);
                            myProcess[i].Refresh();
                            return true;
                        }
                    }
                }            return false;
            }
      

  16.   

    这样的帖子太多了吧?版主没必须推荐吧?
    第一个问题已经有人解决了,用互斥体。
    第二个问题我来解决吧
    [DllImport("user32")]
    static extern void SwitchToThisWindow(IntPtr hwnd,bool restore);
    //hwnd是要激活的窗口句柄,restore指定如果窗口最小化后是否还原这10分我收下了。
      

  17.   

    1、用窗口标题来区别:也许他人的程序也碰巧用同样的标题 
    2、遍历进程:用进程名类区分。缺点:可能有相同的进程名;程序被改名后将有不同的进程名 
    3、利用全局原子Atom:在启动程序时注册全局原子,在关闭程序时删除全局原子。但是如果进程被强行结束 就不会删除全局原子 
    4、利用互斥变量Mutex:与全局原子相同,在强行结束进程时无法删除Mutex 
    http://zhidao.baidu.com/question/80574260.html
      

  18.   

    经测试可用,借用30楼兄弟的代码:using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Runtime.InteropServices;namespace RegexForm
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                if (!HasRun())
                {
                    Application.Run(new Form1());
                }
            }
            [DllImport("user32.dll")]
            private static extern bool ShowWindow(IntPtr hWnd, long nCmdShow);        [DllImport("user32.dll")]
            private static extern bool SetForegroundWindow(IntPtr hWnd);        static bool HasRun()
            {
                Process currentProcess = Process.GetCurrentProcess();
                //查找进程名,如 RegexForm.exe进程
                Process[] myProcess = Process.GetProcessesByName("RegexForm");
                //第一次会没有这个进程名
                if (myProcess.Length == 0)
                {
                    return false;
                }
                //通常情况下myProcess.length只会是1
                for (int i = 0; i < myProcess.Length; i++)
                {
                    if (currentProcess.Id != myProcess[i].Id)
                    {
                        SetForegroundWindow(myProcess[i].MainWindowHandle);
                        myProcess[i].StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                        ShowWindow(myProcess[i].MainWindowHandle, 1);
                        myProcess[i].Refresh();
                        return true;
                    }
                }
                return false;
            }
        }
    }
      

  19.   

      学习 学习 
    http://www.sssyb.cn/ons/?502-1.html
      

  20.   

    System.Diagnostics.Process Proc=null;
            private void ShowExec()
            {
                if(null == Proc || Proc.HasExited )
                {
                    System.Diagnostics.ProcessStartInfo p = null;
                    p = new ProcessStartInfo(_sExeName, "");
                    p.WorkingDirectory = _sCurPath;//设置此外部程序所在目录
                    p.WindowStyle = ProcessWindowStyle.Normal;//在调用外部exe程序的时候,控制台窗口不弹出
                    //如果想获得当前路径为
                    //string path = System.AppDomain.CurrentDomain.BaseDirectory;                Proc = System.Diagnostics.Process.Start(p);//调用外部程序
                }
                else
                {
                    SendCmd("ReDraw");
                }
                
            }
      

  21.   

                bool bCreatedNew;
                Mutex m_CheckProcess = new Mutex(false, "_SystemBusinessAPP", out bCreatedNew);
                //确保只能打开一个进程
                if (bCreatedNew)
                    Application.Run(new FrmFaxMain());
                else
                    MessageBox.Show("应用程序已经启动!");  
      

  22.   

    //获取指定的进程名
    System.Diagnostics.Process[] prProcesses =
                    System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
    //如果获取的进程名多于一个(本身也有一个嘛~)
    if (prProcesses.Length > 1)

            MessageBox.Show("已启动过了一个实例!");//这句话可以换成弹出原窗口的代码。 
            //退出 
            return; 

      

  23.   

    方法一:使用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并不是我想要得,虽说在后面加了文件目录判断,但是其含有潜在的问题(前面已经说出来)。不过,第一种方法也有缺陷,就是扩展性操作不方便,例如:让程序只运行一次,如果程序已经运行,把它弹出并显示到最前面。对于此,后一种方法就很有优势了。
    在c#项目的主入口点加入以下代码:using System.Diagnostics;
    using System.IO;        static void Main()
            {
                string MName = Process.GetCurrentProcess().MainModule.ModuleName;
                string PName = Path.GetFileNameWithoutExtension(MName);
                Process[] myProcess = Process.GetProcessesByName(PName);
                if (myProcess.Length > 1)
                {
                    MessageBox.Show("系统已经在运行中!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new frmLogin());
                }
            }
      

  24.   

    我认同37楼的说法。但遍历标题,可能会碰巧遇到标题相同的程序。遍历进程名,除了也碰巧遇到进程名相同的可能外还有可能进程被改名。
    是用全局变量或者互斥可能存在非法关闭的情况。但,我们还应该结合程序的需要和用户的情况,假如程序一般不会被非法关闭,那么全局变量或者互斥是可以的。假如你的进程名和标题非常大众话(比如,Form.exe,1.exe,窗口1,……)或者本身就存在这样名字的程序(比如,QQ,IEXPLORE,editplus……),可能会存在很多相同进程名或标题的程序,那么遍历标题和进程名很明显是不可行的。但是如果给进程起个很独特的名字或者很独特的标题(比如www_yes1000_com_qq.exe,),一般不可能会出现相同名字或标题的进程,那遍历进程名或标题也可以。
      

  25.   

    方法一: 
    [STAThread] 
    static void Main(string[] args) 

    if (!IsRun()) 

    System.Windows.Forms.Application.Run(new frm1()); 

    else 

    System.Windows.Forms.MessageBox.Show("程序已经运行"); 


    private bool IsRun() 

    int i=0; 
    Process[] ps=Process.GetProcesses(); 
    foreach(Process p in ps) 

    if (p.ProcessName.ToLower()=="自身程序名称(显示在系统任务列表中名称)") 
    i++; 

    return i <2;  //包括自身 
    }
      

  26.   

    方法二: 
    /// <summary> 
    /// Start 的摘要说明。 
    /// </summary> 
    public class Start 

    [DllImport("User32.dll")] 
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); 
    [DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr hWnd); 
            
    private const int WS_SHOWNORMAL = 1; public Start() 


    /// <summary> 
    /// 应用程序的主入口点。 
    /// </summary> 
    [STAThread] 
    static void Main() 

    if(!GetRunningInstance(true)) 

    Application.Run(new frmMdi()); 


    public static bool GetRunningInstance(bool AutoActive) 

    Process currentProcess = Process.GetCurrentProcess(); //获取当前进程 
    //获取当前运行程序完全限定名 
    string currentFileName = currentProcess.MainModule.FileName; 
    //获取进程名为ProcessName的Process数组。 
    Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName); 
    //遍历有相同进程名称正在运行的进程 
    bool r=false; 
    foreach (Process process in processes) 

    if (process.MainModule.FileName == currentFileName) 

    if (process.Id != currentProcess.Id) //根据进程ID排除当前进程 

    r=true; 
    if(AutoActive) 
    HandleRunningInstance( process);//返回已运行的进程实例 



    return r; 

    public static bool GetRunningInstance() 

    return GetRunningInstance(false); 

    public static bool HandleRunningInstance(Process instance) 

    //确保窗口没有被最小化或最大化 
    ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); 
    //设置为foreground window 
    return SetForegroundWindow(instance.MainWindowHandle); 
    } }
      

  27.   

    设计模式中的单例模式(singlton)可以吗?
      

  28.   

    总结下:
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace WindowsApplication1
    {
        static class Program
        {
            [DllImport("user32.dll")]
            private static extern bool ShowWindow(IntPtr hWnd, long nCmdShow);        [DllImport("user32.dll")]
            private static extern bool SetForegroundWindow(IntPtr hWnd);        static bool HasRun()
            {
                Process currentProcess = Process.GetCurrentProcess();
                Process[] myProcess = Process.GetProcessesByName(Application.ProductName);
                if (myProcess.Length > 1)
                {
                    for (int i = 0; i < myProcess.Length; i++)
                    {
                        if (currentProcess.Id != myProcess[i].Id)
                        {
                            SetForegroundWindow(myProcess[i].MainWindowHandle);
                            myProcess[i].StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
                            ShowWindow(myProcess[i].MainWindowHandle, 1);
                            myProcess[i].Refresh();
                            return true;
                        }
                    }
                }            return false;
            }
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {            Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //如果实例在运行,则显示正在运行实例
                if (!HasRun())
                    Application.Run(new Form1());        }
        }
    }
      

  29.   


    这家伙人品有问题 ,楼主明确用C# 你硬要上VB上来
      

  30.   

    //获取指定的进程名
    System.Diagnostics.Process[] prProcesses =
                    System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
    //如果获取的进程名多于一个(本身也有一个嘛~)
    if (prProcesses.Length > 1)

            MessageBox.Show("已启动过了一个实例!");//这句话可以换成弹出原窗口的代码。 
            //退出 
            return; 

      

  31.   

    原生的API就是使用Mutex.
    使用Processes信息判断是有问题的.
      

  32.   

    参考下 
    http://hi.baidu.com/hetaoos/blog/item/2abda7185ab63a0334fa415f.html 
    http://www.builder.com.cn/2007/0907/495324.shtml 
    http://www.cnblogs.com/wequst/archive/2009/01/08/1371754.html