程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 防止程序多重啟動

防止程序多重啟動

編輯:匯編語言

此文章是接續憐香的"DOS到Win32"系列教程第14篇的後續,閱讀之前推薦查看前續文章

正如憐香所說,命令行參數在Windows中是無處不在的,只是一般感覺不到,雙擊一個txt文件,Windows會啟動記事本程序並把txt的路徑做為參數提供給它,這當然相當的快捷,一般在打開一個文件時會再一次啟動相關聯的程序,但是你會發現很多多文檔(MDI)軟件在運行的情況下不會再次啟動一個新的實例,而是已經運行的程序打開了你再次需要打開的文件,這就是防止程序的多重啟動。

這一篇先講如何防止,下一篇再講如何處理(就是讓已經運行的實例打開下個實例的文件)。

要防止程序多重啟動,有很多的方法,如下:

1.可以使用FindWindow查找程序的標題,此函數成功返回目標窗口句柄,失敗為NULL.

 szWindowName db "Hello World!",0
     ... ...
     invoke FindWindow,NULL,offset szWindowName
     .if eax!=NULL
     invoke WinMain....
     .end if
     invoke ExitProcess,0

這種方法不是很好,因為會有一些軟件的窗口可能與你的窗口標題同名,注意看上面的FindWindow,參考API手冊發現第一個參數是ClassName,窗口類名除自身實例一般是唯一的,這種方法一般完全可行:

2.使用FindWindow查找程序的窗口類名,函數成功返回目標窗口句柄,失敗為NULL.

 szClassName db "WINASM_CLASS!",0
     ... ...
     invoke FindWindow,offset szClassName,NULL
     .if eax!=NULL
     invoke WinMain....
     .end if
     invoke ExitProcess,0

但是這種方法缺點就是,當程序沒有標准的窗口或是以對話框為主窗口的程序就不適用了,沒有標准窗口的程序當然沒有類名,而以對話框為主窗口的程序的話也不行,因為默認對話框的類名都是#32768,這個當然無法依此來判斷實例是否已運行.

3.創建一個Mutex(互斥)對象,這是一個系統全局標識,創建後所有的程序都可以訪問到.此函數成功返回Mutex對象的句柄,失敗返回NULL,但是一般都是通過GetLastError獲得錯誤編號進行判斷.

.data
      szMutex db "_Me?",0
.data?
      hMutex dd ?
      hInstance dd ?
.CODE
START:
      invoke GetModuleHandle,NULL
      mov hInstance,eax
      invoke
CreateMutex,NULL,TRUE,offset szMutex
      mov hMutex,eax
      invoke GetLastError        獲得最後發生的錯誤編號
      cmp eax,ERROR_ALREADY_EXISTS  已經存在
      jz @F
      invoke WinMain...
      invoke ReleaseMutex,hMutex     只有在正常運行後才釋放Mutex對象
      @@:
      invoke ExitProcess,0

4.還有其它方法,如在程序啟動時在同目錄或Windows臨時目錄下創建一個文件,退出刪除它,那麼第二個以上的實例運行後首先判斷是否存在這個文件,存在則退出,不存在則啟動,如果一個程序使用到了INI則更方便,和上面說的一樣,在啟動時設置某個鍵,退出時再設為0,第二個以上的實例則以此鍵為"互斥對象"。還有往注冊表中寫一個鍵,方法和上面是一樣的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved