如何控制一个程序只能有一个进程?[From csdn]

Windows是多进程操作系统,框架生成的应用程序可以多次运行,形成多个运行实  
  例。但在有些情况下为保证应用程序的安全运行,要求程序只能运行一个实例,比  
  如程序要使用只能被一个进程单独使用的特殊硬件(例如调制解调器)时,必须限  
  制程序只运行一个实例。  
  这里涉及两个基本的问题,一是在程序的第二个实例启动时,如何发现该程序已有  
  一个实例在运行,而是如何将第一个实例激活,而第二个实例退出。  
   
  对于第一个问题,可以通过给应用程序设置信号量,实例启动时首先检测该信号量  
  ,如已存在,则说明程序已运行一个实例。  
   
  第二个问题的难点是获取第一个实例的主窗对象指针或句柄,然后便可用  
  SetForegroundWindow来激活。虽然FindWindow函数能寻找正运行着的窗口,但该  
  函数要求指明所寻找窗口的标题或窗口类名,不是实现通用方法的途径。我们可以  
  用Win   32   SDK函数SetProp来给应用程序主窗设置一个特有的标记。用  
  GetDesktopWindow可以获取Windows系统主控窗口对象指针或句柄,所有应用程序  
  主窗都可看成该窗口的子窗口,即可用GetWindow函数来获得它们的对象指针或句  
  柄。用Win   32   SDK函数GetProp查找每一应用程序主窗是否包含有我们设置的特定  
  标记便可确定它是否我们要寻找的第一个实例主窗。使第二个实例退出很简单,只  
  要让其应用程序对象的InitInstance函数返回FALSE即可。此外,当主窗口退出时  
  ,应用RemoveProp函数删除我们为其设置的标记。 

BOOL CTestApp::InitInstance()

{

    /********************************/

    //   用应用程序名创建信号量 

    HANDLE   hSem   =   CreateSemaphore(NULL, 1, 1, m_pszExeName);  

    //   信号量已存在? 

    //   信号量存在,则程序已有一个实例运行 

    if   (GetLastError() == ERROR_ALREADY_EXISTS)  

    {  

        //关闭信号量句柄 

        CloseHandle(hSem);  

        //寻找先前实例的主窗口 

        HWND   hWndPrevious   = ::GetWindow(::GetDesktopWindow(), GW_CHILD);  

        while(::IsWindow(hWndPrevious))  

        {  

            // 检查窗口是否有预设的标记?  

            //有,则是我们寻找的主窗 

            if   (::GetProp(hWndPrevious,   m_pszExeName))  

            {  

                //   主窗口已最小化,则恢复其大小 

                if   (::IsIconic(hWndPrevious))  

                    ::ShowWindow(hWndPrevious,    

                    SW_RESTORE);  

                //   将主窗激活 

                ::SetForegroundWindow(hWndPrevious);  

                //   将主窗的对话框激活 

                ::SetForegroundWindow(  

                    ::GetLastActivePopup(hWndPrevious));  

                //   退出本实例 

                return   FALSE;  

            }  

            //   继续寻找下一个窗口 

            hWndPrevious   =   ::GetWindow(hWndPrevious,    

                GW_HWNDNEXT);  

        }  

        //   前一实例已存在,但找不到其主窗 

        //   可能出错了 

        //   退出本实例 

        return   FALSE;  

    }

AfxEnableControlContainer();

    //... ...

}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

        return -1;

    //设置寻找标记 ljs  

    ::SetProp(m_hWnd,   AfxGetApp()->m_pszExeName,(HANDLE)1);  

    m_GameLobbyDlg.Create(this);

    m_bInit = TRUE;

    return 0;

}

CMainFrame::~CMainFrame()

{

    //删除寻找标记 

    ::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName); 

}

法二:

互斥体

    ::CreateMutex(NULL,TRUE,m_pszExeName);  

    if(GetLastError()==ERROR_ALREADY_EXISTS)  

    {  

        //   寻找先前实例的主窗口 

        HWND   hWndPrevious   =   ::GetWindow(::GetDesktopWindow(),   GW_CHILD);  

        while(::IsWindow(hWndPrevious))  

        {  

            if(::GetProp(hWndPrevious,m_pszExeName))  

            {  

                //   主窗口已最小化,则恢复其大小 

                if   (::IsIconic(hWndPrevious))  

                    ::ShowWindow(hWndPrevious,   SW_RESTORE);  

                //   将主窗激活 

                ::SetForegroundWindow(hWndPrevious);  

                //   将主窗的对话框激活 

                ::SetForegroundWindow(::GetLastActivePopup(hWndPrevious));  

                //   退出本实例 

                return   FALSE;  

            }  

            hWndPrevious   =   ::GetWindow(hWndPrevious,   GW_HWNDNEXT);  

        }  

        return   FALSE;   

    }

 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

c#:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

public class OneInstnace
{
    [STAThread]
    public static void Main()
    {
        //Get   the   running   instance.  
        Process instance = RunningInstance();
        if (instance == null)
        {
            //There   isn't   another   instance,   show   our   form.  
            Application.Run(new Form());
        }
        else
        {
            //There   is   another   instance   of   this   process.  
            HandleRunningInstance(instance);
        }
    }

    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;
    }


    public static void HandleRunningInstance(Process instance)
    {
        //Make   sure   the   window   is   not   minimized   or   maximized  
        ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
        //Set   the   real   intance   to   foreground   window  
        SetForegroundWindow(instance.MainWindowHandle);
    }

    [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;
}

 也可以使用互斥体Mutex类型完成此功能。见如下代码:  
          [STAThread]  
          public   static   void   Main(string[]   args)    
          {  
                    //声明互斥体。  
                    Mutex   mutex   =   new   Mutex(false,   "ThisShouldOnlyRunOnce");  
                    //判断互斥体是否使用中。  
                    bool   Running   =   !mutex.WaitOne(0,   false);  
                    if   (!   Running)  
                            Application.Run(new   FormLogin());  
                    else  
                            MessageBox.Show("应用程序已经启动!");  
          }  

原文地址:https://www.cnblogs.com/anorthwolf/p/process.html