全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2296
推到 Plurk!
推到 Facebook!

有關防止程式重複執行的一些心得

 
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-12-27 14:29:00 IP:203.75.xxx.xxx 未訂閱
我想這個問題已被討論很多次了, 我也曾在這個版上提出同樣的問題, 下面是我找了一些資料加上 RaynorPao 等熱心人士的指點, 所整理的一個心得. 要防止程式重複執行, 在 VB 中的 App 中有一個 preInstance 可以輕易得知目前的程式是否為第一個 instance, 不幸在 BCB 中卻沒有類似的機制, 不過我們可用 CreateMutex 的方法來測試同樣的 Mutex Object 是否已被 create 來確保程式是第一次執行, 其宣告如下,    HANDLE CreateMutex(     LPSECURITY_ATTRIBUTES lpMutexAttributes,     BOOL bInitialOwner,             LPCTSTR lpName             );    詳細用法請參考 BCB 的 help 或 MSDN, 這裡我想要提出來的是一般大家在用這個 API 時 lpName 經常使用任意取的名字, 或是直接用 Form 的 Caption, 這樣固然方便但是不能確保名字是唯一, 每次都要想不同的名字又太累, 所以我建議可以做個小修改,    AnsiString asTemp00 = (long)(GetWindowLong(Application->Handle,GWL_HINSTANCE)); CreateMutex(NULL,false,asTemp00.c_str()); if (GetLastError() == ERROR_ALREADY_EXISTS)     Application->Terminate();    以程式的 Instance Handle 來個名稱就萬無一失了, 有一點要注意的是在程式結束時要記得 ReleaseMutex(). 另外不知有沒有人想要做到如果之前已有一個 Instance 在執行的話, 就先把之前的程式結束掉, 以後者取代之. 因為如果用 FindWindow 想要去取得前一個程式的 Handle 的話, 找到的總會是自己, 所以必須另找方法, 我所想到的方法是在程式執行時先以 Instance 為 key 把自己的 Handle 存起來, 如此第二個程式在執行時發現已有自己的同類在執行就去讀取它的 Handle, 而對它送出 WM_CLOSE 的 message, 實作如下,    #include  #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; HWND hMutex; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { TRegistry * rgpSystem = new TRegistry;; Caption = Now(); AnsiString asTemp00 = (long)(GetWindowLong(Application->Handle,GWL_HINSTANCE)); rgpSystem->OpenKey(asTemp00,true); CreateMutex(NULL,false,asTemp00.c_str()); if (GetLastError() == ERROR_ALREADY_EXISTS) SendMessage((HWND)rgpSystem->ReadInteger("Handle"),WM_CLOSE,NULL,NULL); rgpSystem->WriteInteger("Handle",(int)(this->Handle)); rgpSystem->CloseKey(); delete rgpSystem; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { ReleaseMutex(hMutex); } //--------------------------------------------------------------------------- 這些 code 沒有用到什麼高深的理論, 可是我想還算實用, 野人獻曝, 謹供大家參考. Jesse Chan
------
Jesse Chan
xfile
初階會員


發表:21
回覆:80
積分:25
註冊:2004-10-02

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-28 04:34:39 IP:219.80.xxx.xxx 未訂閱
引言: 詳細用法請參考 BCB 的 help 或 MSDN, 這裡我想要提出來的是一般大家在用這個 API 時 lpName 經常使用任意取的名字, 或是直接用 Form 的 Caption, 這樣固然方便但是不能確保名字是唯一, 每次都要想不同的名字又太累, 所以我建議可以做個小修改, AnsiString asTemp00 = (long)(GetWindowLong(Application->Handle,GWL_HINSTANCE)); CreateMutex(NULL,false,asTemp00.c_str()); if (GetLastError() == ERROR_ALREADY_EXISTS) Application->Terminate(); 以程式的 Instance Handle 來個名稱就萬無一失了, 有一點要注意的是在程式結束時要記得 ReleaseMutex().
回報一下,我在兩個不同程式中用這個方法,還是會 "強碰", 這方法有破綻,雖然我不知道原因為何。 我建議還是累一點,自己取個名字比較保險
Fm
初階會員


發表:19
回覆:66
積分:37
註冊:2003-10-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-03-24 14:51:19 IP:220.130.xxx.xxx 未訂閱
我是習慣寫在project.cpp底下... 因為我想那裡是程式的起源.... //--------- 偏聽則誨,兼聽則明 如果那個人是我..那該多好
系統時間:2024-05-03 15:32:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!