VCC如何防止程序同時啟動多次_第1頁
VCC如何防止程序同時啟動多次_第2頁
VCC如何防止程序同時啟動多次_第3頁
VCC如何防止程序同時啟動多次_第4頁
VCC如何防止程序同時啟動多次_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、如何防止程序同時啟動多次(即互斥訪問)2009-02-11 14:41方法1:在tnittnstance里面加上iiwnd oldllwnd = null;enumwindows(enumwndproc, (lparam)&oldhwnd);if(oldhwnd != null):showwi ndow (ol dhwnd, sw_showaxtmtzed);:sctforcgroundwindow(oldhwnd);return false;這個也是比較簡單的=方法的分割線=方法2:有很多種方法。例如:使應用程序只能運行一個實例windows是多進程操作系統(tǒng),框架生成的應用程序可以多

2、次運行,形成多個運行 實例。但在有些情況下為保證應用程序的安全運行,要求程序只能運行一個實例,比如 程序要使用只能被一個進程單獨使用的特殊硬件(例如調(diào)制解調(diào)器)吋,必須限制 程序只運行一個實例。這里涉及兩個基木的問題,一是在程序的第二個實例啟動時,如何發(fā)現(xiàn)該程序已 有一個實例在運行,而是如何將第一個實例激活,而第二個實例退出。對于第一個問題,可以通過給應用程序設置信號量,實例啟動時首先檢測該信號 量,如已存在,則說明程序已運行一個實例。第二個問題的難點是獲取第一個實例的主窗對象指針或句柄,然后便可用 setforegroundwindow來激活。雖然findwindow函數(shù)能尋找正運行著的窗口

3、, 但該函數(shù)要求指明所尋找窗口的標題或窗口類名,不是實現(xiàn)通用方法的途徑。我們可以用win32 sdk函數(shù)setprop來給應用程序主窗設置一個特有的標記。 用getdesktopwindow可以獲取windows系統(tǒng)主控窗口對象指針或句柄,所有應 用程序主窗都可看成該窗口的子窗口,即可用getwindow函數(shù)來獲得它們的對象指針 或句柄。用win32 sdk函數(shù)getprop查找每一應用程序主窗是否包含有我們設置的特 定標記便可確定它是否我們要尋找的第一個實例主窗。使第二個實例退幽很簡單,只 要讓其應用程序?qū)﹀璧膇nitlnstancc函數(shù)返回false即可。此外,當主窗口退出 時,應用rem

4、oveprop函數(shù)刪除我們?yōu)槠湓O置的標記。下面的tni ttnstance> oncreate和ondestroy函數(shù)代碼將實現(xiàn)上述的操作:bool cellipsewndapp:initlnstance()/用應用程序名創(chuàng)建信號量handle hsem 二 createsemaphore (?4ull, 1, 1, m pszexename);/信號量已存在?/信號量存在,則程序已有一個實例運行if (getlasterroro 二二 error_already_exists)/關閉信號量句柄closehandle(hsem);/尋找先前實例的主窗口hwnd hwndprevious

5、= :getwindow(:getdesktopwindow(), gw child);whi1e (:tswindow(hwndprevious)/檢查窗口是否有預設的標記?/有,則是我們尋找的主窗if (:getprop(hwndprevious, mpszexename) /主窗口已最小化,則恢復其大小if (:islconic(hwndprevious):showwindow(hwndprevious, sw restore);/將主窗激活:sctforcgroundwindow (hwndprevious);/將主窗的對話框激活:setforegroundwindow(:getlas

6、tactivepopup(hwndprevious);/退岀本實例 return false;/繼續(xù)尋找下一個窗口hwndprevious = :getwindow(hwndprevious, gw_hwndnext); "/前一實例己存在,但找不到其主窗/可能岀錯了/退出本實例return false;afxenablecontrolcontainer ();/ standard initialization/ if you are not using those features emd wish to reduce the size / of your final execut

7、able, you should remove from the following / the specific initialization routines you do not need.#ifdef _afxdllenable3dcontrols() ; / cal 1 this when using mfc in a shared dllseiseenable3dcontrolsstatic();/ call this when linking to mfc statically sendifcellipsewnddlg dig;m_pmainwnd 二 &dig;int

8、nresponse = dig. domodal();if (nresponse = idok)/ todo: place code here to handle when the dialog is/ dismissed with okelse if (nresponse = idcancel)/ todo: place code here to handle when the dialog is/ dismissed with cancel/ since the dialog has been closed, return false so that we exit the / appli

9、cation, rather than start the application's message pump, return false;int ce11ipsewnddlg:oncreate(lpcreatestruct ipcreatestruct) if (cdialog:oncreate(ipcreatestruct) = 1) return -1;/設置尋找標記:setprop(mhwnd, afxgetapp()->m_pszexename, (handle)1); return 0;void cellipsewnddlg:0ndestroy()cdialog:0

10、ndestroy();/刪除尋找標記:removeprop (m_hwnd, afxgetapp()->m_pszexename);對以上代碼的補充:查看代碼和vc的幫助后,發(fā)現(xiàn)問題在于原文在創(chuàng)建信號量和設置尋找標記吋使 用的是cwinapp的成員變量m_pszexename,該成員變量其實是應用程序執(zhí)行文件 的名稱去掉擴展名后的部分,而不是應用程序名。真正的應用程序名應為成員變量m_pszappnamc,于是將用到m_pszexename的三處代碼均改為m_pszappname,重新編譯執(zhí)行,情 況消失。最后再提供一個方法和一個信息:另一種使應用程序只能運行一個實例的方法,只需在ini

11、tlnstanceo的最開始 添加下列語句即可:handle m_hmutex=createmutex(nui丄,true, m pszappname);if (gctlasterror()=error_already_exists) return false; 但這種方法的不足之處是不能將己經(jīng)啟動的實例激活。=方法的分割線=方法3:a.使用編譯器來實現(xiàn)(使用mfc框架):在.cpp文件開頭加上以下兒行:pragma data seg(,zshared,z)int volatile g_lappinstance =0; pragma data sego我們來看一下上面的內(nèi)容:第一句 pragm

12、a data_scg(,sharcd,/)創(chuàng)建一個稱為 shared 的新節(jié)。第二句 int volatile g_lapplnstance =0 將 g_lapplnstance 放入 shared 節(jié) 中。注意此時只有將g_lappinstance初始化,編譯器才會將其放入shared節(jié)中, 否則,將放入shared以外的節(jié)。(實際上visual c+編譯器提供了一個allocate 說明符,使我們可以將數(shù)據(jù)放到任何節(jié)中。) 第三句指示編譯器shared節(jié)結束。jtpragma comment(linker, "/section:shared, rws)這一句,我們使編譯鏈接器知

13、道我們的shared節(jié)具有讀,寫,共享的屬性。這 是我們實現(xiàn)互斥運行的關鍵。這樣我們就可以在應用程序之間的多個實例之間共 享 g_lappinstancc 變量。在 initlnstance()函數(shù)中加入:if (+g_lapplnstance>l) "afxmessagebox(,z程序己經(jīng)運行! “);return false;以上代碼的作用是在程序是開始對g_lapplnstancd加1 ,如果發(fā)現(xiàn)其值大于1, 那么顯示 message box ,并返false。(注意:在 mfc 中女u果 initlnstance 返冋false,程序?qū)⒉粫贿\行!)=還是分割線方法的

14、=方法4:使用命名互斥對象:使用apt函數(shù)createmutex來創(chuàng)建命名互斥對象來實現(xiàn)程序互斥是一個比較通用 的方法,我們可以在ininlnstancco函數(shù)加入如下代碼:11andle hobjcct = createmutex(null, false, ljpxyxc);if(getlasterroro = error_already_exists)closehandle(hobject);afxmcssagcbox(,z程序已經(jīng)運行!);return false;以上的createmutext函數(shù)創(chuàng)建一個稱為“l(fā)jpxyxc”的命名的互斥對象,當程序 的第二個實例運例吋,調(diào)用creat

15、emutex返冋error_already_extstso我們根 據(jù)這個值來實現(xiàn)程序的互斥運行。還有其他的哦方法其他:oncreate (lpcreatestruct 1 pcreatestruct)里面 m_hmutex=openmutex(mutex_all_access, false, 自己取一個名字);if (m_hmutex=null)createmutex(null, true,"自己取一個名字);el semessagebox c程序已經(jīng)運行!);return -1;在.h文件的類聲明里面添加:handle m hmutex;=再其他=用命名的互斥!在你的程序啟動是先判斷一個互斥a有沒有,如果互斥a不存在,就說明該程序沒 有啟動,則啟動該程序并創(chuàng)建該互斥a,在程序結束時銷毀互斥a如果在啟動程序時發(fā)向互斥a存在,怎說明程序已經(jīng)啟動了,則程序

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論