当前位置:  编程技术>c/c++/嵌入式

让应用程序只运行一个实例的实现方法

    来源: 互联网  发布时间:2014-10-13

    本文导语:  在我们的程序当中如果要实现类似《360软件管家》的功能,就要解决两个问题,首先是要判断该程序已有一个实例在运行,其次是要将已运行的应用程序实例激活,同时退出第二个应用程序实例。 对于第一个问题,我们可以通...

在我们的程序当中如果要实现类似《360软件管家》的功能,就要解决两个问题,首先是要判断该程序已有一个实例在运行,其次是要将已运行的应用程序实例激活,同时退出第二个应用程序实例。

对于第一个问题,我们可以通过设置命名互斥对象或命名信标对象,在程序启动的时候检测互斥对象或信标对象,如互斥对象或信标对象已存在,则可以判断此程序已有一个实例正在运行。

第二个问题是如何找到已经运行的应用程序实例,如果我们能够找到已运行实例主窗口的指针,即可调用SetForegroundWindow来激活该实例。我们可以通过两种形式找到已运行实例的主窗口,一种形式是通过调用FindWindowEx去查找正在运行的窗口的句柄,这种方式用得比较多一些,而本文通过另一种形式去查找正在运行的窗口的句柄。通过调用SetProp给应用程序主窗口设置一个标记,用GetDesktopWindow 可以获取Windows环境下的桌面窗口的句柄,所有应用程序的主窗口都可以看成该窗口的子窗口,接着我们就可以用GetWindow函数来获得这些窗口的句柄。然后再用Win32 SDK函数GetProp查找每一个应用程序的主窗口是否包含有我们设置的标记,这样就可以找到我们要找的第一个实例主窗口。

下面演示代码是以一个单文档应用程序为例,工程名字是Mutex。

代码如下:

1、在应用程序类InitInstance()函数中判断是否已有一个应用程序实例正在运行。

BOOL CMutexApp::InitInstance()

{

       //创建命名信标对象。

       HANDLE hSem=CreateSemaphore(NULL,1,1,"维新");

       if(hSem)  //信标对象创建成功。

       {

              //信标对象已经存在,则程序已有一个实例在运行。

              if(ERROR_ALREADY_EXISTS==GetLastError())

              {                 

                     CloseHandle(hSem);      //关闭信号量句柄。

 

//获取桌面窗口的一个子窗口。

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

 

                     while(::IsWindow(hWndPrev))

                     {

                     //判断窗口是否有我们预先设置的标记,如有,则是我们寻找的窗口,并将它激活。

                            if(::GetProp(hWndPrev,"维新"))  

                            {

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

                                   if (::IsIconic(hWndPrev))    

                                          ::ShowWindow(hWndPrev,SW_RESTORE);

 

                                   //将应用程序的主窗口激活。

                                   ::SetForegroundWindow(hWndPrev);

                                   return FALSE;                      //退出实例。

                            }

                            //继续寻找下一个窗口。

                            hWndPrev = ::GetWindow(hWndPrev,GW_HWNDNEXT);

                     }

                   

                     AfxMessageBox("已有一个实例在运行,但找不到它的主窗口!");

              }

       }

       else

       {

              AfxMessageBox("创建信标对象失败,程序退出!");

              return FALSE;

       }

 

       AfxEnableControlContainer();

 

       // Standard initialization

       // If you are not using these features and wish to reduce the size

       //  of your final executable, you should remove from the following

       //  the specific initialization routines you do not need.

     

#ifdef _AFXDLL

       Enable3dControls();                     // Call this when using MFC in a shared DLL

#else

       Enable3dControlsStatic();      // Call this when linking to MFC statically

#endif

 

       // Change the registry key under which our settings are stored.

       // TODO: You should modify this string to be something appropriate

       // such as the name of your company or organization.

       SetRegistryKey(_T("Local AppWizard-Generated Applications"));

 

       LoadStdProfileSettings();  // Load standard INI file options (including MRU)

 

       // Register the application's document templates.  Document templates

       //  serve as the connection between documents, frame windows and views.

 

       CSingleDocTemplate* pDocTemplate;

       pDocTemplate = new CSingleDocTemplate(

              IDR_MAINFRAME,

              RUNTIME_CLASS(CMutexDoc),

              RUNTIME_CLASS(CMainFrame),       // main SDI frame window

              RUNTIME_CLASS(CMutexView));

       AddDocTemplate(pDocTemplate);

 

       // Parse command line for standard shell commands, DDE, file open

       CCommandLineInfo cmdInfo;

       ParseCommandLine(cmdInfo);

 

       // Dispatch commands specified on the command line

       if (!ProcessShellCommand(cmdInfo))

              return FALSE;

 

       // The one and only window has been initialized, so show and update it.

       m_pMainWnd->ShowWindow(SW_SHOW);

       m_pMainWnd->UpdateWindow();

 

       return TRUE;

}

2、在框架类的OnCreate()函数中设置查找标记。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

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

              return -1;

     

       if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

              | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

              !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

       {

              TRACE0("Failed to create toolbar/n");

              return -1;      // fail to create

       }

 

       if (!m_wndStatusBar.Create(this) ||

              !m_wndStatusBar.SetIndicators(indicators,

                sizeof(indicators)/sizeof(UINT)))

       {

              TRACE0("Failed to create status bar/n");

              return -1;      // fail to create

       }

 

       // TODO: Delete these three lines if you don't want the toolbar to

       //  be dockable

 

       m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

       EnableDocking(CBRS_ALIGN_ANY);

       DockControlBar(&m_wndToolBar);

 

     

       //设置查找标记。

       ::SetProp(m_hWnd,"维新",(HANDLE)1);

 

       return 0;

}

3、在程序退出是删除设置的标记,在框架类中响应WM_DESTROY消息,进行处理。

void CMainFrame::OnDestroy()

{

       CFrameWnd::OnDestroy();

     

       // TODO: Add your message handler code here

       //删除所设置的标记。

       ::RemoveProp(m_hWnd,"维新");

}

至此,使应用程序只运行一个实例的功能就完成了。

 


    
 
 

您可能感兴趣的文章:

  • 使用mutex实现应用程序单实例运行代码分享
  • linux 下如何实现控制所有应用程序为单实例的????
  • C#实现只运行单个实例应用程序的方法(使用VB.Net的IsSingleInstance)
  • iis应用程序池监控方法实例
  • C#实现点击按钮退出应用程序实例
  • C# 禁止应用程序多次启动的实例
  • 大家帮忙分析一下程序在哪个地方出了错?管道应用实例.
  • C语言程序,软定时器应用的实例
  • 怎样让linux启动后不运行桌面而是直接运行某个应用程序呢?
  • 怎样开发在LINUX 上运行的应用程序,像WINDOWS桌面应用程序一样
  • jdk1.4 单独运行java应用程序单独运行出现环境变量问题?问题解决马上给分!!
  • 运行什么程序都提示没有找到msvbvm5.0.dll,因此这个应用程序未能启动
  • 为什么我写的应用程序不能持续运行?
  • 手动执行应用程序ok,但用crontab(在正确的用户名下)运行应用程序就报-12545(tns连接错误),怎么解决?
  • 怎样让java应用程序独立运行?
  • linux redhat9.0自带的应用程序如何运行?
  • [求助]如何在linux下运行windows应用程序????
  • freebsd下定期运行java应用程序
  • 新手提问,应用程序运行:Permission denied错误
  • java.exe-应用程序错误(程序一运行就报错)
  • 嵌入式Linux换了内核后,运行应用程序显示Killed
  • 为什么应用程序必须在目标机上才能运行?
  • 通过FTP如果运行远程服务器上一个应用程序?
  • 请问如何在red hat8.0中运行.bin扩展名的应用程序
  • 简单问题:solaris下如何在后台运行应用程序?
  • 请问怎么把一个应用程序作为一个服务来运行啊?
  • 怎么运行java的应用程序
  • 怎样是编好的java application在windows上像windows应用程序一样直接运行
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 重装服务器后IIS网站错误(应用程序中的服务器错误)
  • 如何将应用程序加到桌面或应用程序组?
  • 我要监测一台远程电脑的状态(未上线/上线但没打开每个应用程序/上线且打开应用程序),该如何作?
  • asp.net应用程序的生命周期和iis应用程序池
  • freebsd下定期运行java应用程序 iis7站长之家
  • 终端打开应用程序,怎样使当终端退出时应用程序不退出.问了好多人,其实很简单.
  • linux 桌面应用程序和web应用程序编写常用的语言
  • 用SecureCRT或Putty 远程启动linux服务器上的一个应用程序,但是当我关掉SecureCRT的时候,应用程序也被关掉了,怎么能够做到我关闭客户
  • QT的应用程序中如何获取程序执行的路径?
  • 请问如何通过telnet的方式启动服务器(solaris)上的用.sh角本方式启动java写的应用程序,在退出telnet时服务器上的应用程序不会退出?
  • 把java源程序生成应用程序有哪些方法?
  • 菜鸟求助:Linux 应用程序后台启动后关闭窗口程序退出
  • 一个程序能否控制其他应用程序?
  • 走虚拟网卡内核程序和走物理网卡应用程序结合问题
  • 学了linux程序设计后能不能编写出应用程序
  • 请问如何设置驱动程序和应用程序的启动顺序和优先级呢?
  • 请问能否在linux实现一个应用程序访问另外一个程序的内存数据?
  • 深入C#任务管理器中应用程序选项隐藏程序本身的方法详解
  • java的应用程序中如何定义一个全局变量,在程序的任何地方都可以修改使用?
  • linux驱动程序是怎样通过内核和应用程序通信,还有是怎样和硬件通信,跪求求解,谢谢高手留言。
  • JAVA 应用程序小程序中能不能运行其它程序(.EXE)的 如果能请问应该怎样调用?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3