| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1542 人关注过本帖, 1 人收藏
标题:这样防止已经运行的程序再次运行?
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
自己編譯爲EXE文件運行一次看看吧,我測試過的,死機也能檢測得出來。

程序代码:
CLEAR ALL 
CLEAR 
IF On_Start()
    frm_Test = CREATEOBJECT("_Test")
    frm_Test.Show
    READ EVENTS
    On_Quit()
ENDIF 
RETURN 

DEFINE CLASS _Test AS Form 
    ShowWindow = 2
    AutoCenter = .T.
    
    PROCEDURE Destroy
        CLEAR EVENTS 
    ENDPROC 
    
ENDDEFINE 

PROCEDURE On_Start()
    PUBLIC gcFlagFileName AS Character, gnFlagFileHandle AS Integer
    
    gcFlagFileName = "D:\Started.vfp"
    gnFlagFileHandle = Null
    IF FILE(gcFlagFileName)
        gnFlagFileHandle = FOPEN(gcFlagFileName)
        IF gnFlagFileHandle == -1
            MESSAGEBOX("本程序不能重複啓動!", 16, "")
            RETURN .F.
        ELSE 
            On_Quit()
        ENDIF 
    ENDIF 
    gnFlagFileHandle = FCREATE(gcFlagFileName)
    
    RETURN .T.
    
ENDPROC 

PROCEDURE On_Quit()
    FCLOSE(gnFlagFileHandle)
    DELETE FILE (gcFlagFileName)
ENDPROC 


注:一定要編譯爲獨立可執行文件!按理APP也可以,不過沒試過。在_SCREEN下肯定不行的,試過了。為什麼在_SCREEN下不行?不知道。

多機、網絡環境不存在禁止重複啓動的問題。基本上就單機有這種需要,此時可將標誌文件放置在本地磁盤上,即是該機已啓動標誌。如果程序中途死機,會有一份屍骸存在,但它是可以打開的,如果無法打開,表明程序在工作中(它佔住了)。樓主自己想辦法隱蔽這些動作和信息,我不寫那部分代碼了。

友情忠告:用API函數做這件事是自找麻煩,它嚴重依賴於系統和軟件版本!

[ 本帖最后由 TonyDeng 于 2011-7-16 01:01 编辑 ]

授人以渔,不授人以鱼。
2011-07-16 00:22
ptyy803
Rank: 2
来 自:上海
等 级:论坛游民
威 望:2
帖 子:193
专家分:64
注 册:2009-6-11
收藏
得分:0 
请问21楼,象你这样的代码怎样编译成EXE文件
2011-07-24 12:04
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 22楼 ptyy803
图片附件: 游客没有浏览图片的权限,请 登录注册

授人以渔,不授人以鱼。
2011-07-24 12:39
ibmlang_002
Rank: 5Rank: 5
来 自:浙江-嘉兴
等 级:贵宾
威 望:18
帖 子:437
专家分:176
注 册:2008-8-30
收藏
得分:0 
Public Handle
DECLARE INTEGER CreateFileMapping IN kernel32.DLL INTEGER hFile, ;
        INTEGER lpFileMappingAttributes,integer flProtect, ;
        INTEGER dwMaximumSizeHigh, INTEGER dwMaximumSizeLow, ;
        STRING lpName
DECLARE INTEGER GetLastError IN kernel32.DLL
DECLARE INTEGER CloseHandle IN kernel32.DLL INTEGER hObject
szname="hello"
Handle = CreateFilemapping(0xFFFFFFFF,0,4,0,128,szname)
   If GetLastError()=183
      DO FORM pd_cf
      READ EVENTS
      
      Return .F.
   Endif

VFP
2011-07-25 11:58
茵梦湖
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:31
帖 子:545
专家分:2180
注 册:2009-4-25
收藏
得分:0 

也可以用 是否产生某临时文件的方法~


lsc ="同路径 同总控程序, 貌似已在运行中~" +chr(10)+chr(10)+"请检查: 1) 确实在运行" +chr(10)+"        2) 未运行, 是因出错等 而残留了文件   "
if "#备"$sys(16) .or.(file("&temp\s_menu0.dbf").and.7=messageb(lsc +chr(10)+chr(10)+chr(10) +"  同路径下 再运行吗??  ", 4+48+256," !!谨慎"))
   ...
endif

 
 

运行效果:

图片附件: 游客没有浏览图片的权限,请 登录注册


2011-07-25 19:21
qingfameng
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:35
帖 子:964
专家分:3019
注 册:2010-2-6
收藏
得分:0 
也谈点看法,不妥之处望大家指教。
1、判断一个程序是否已经运行,在一个程序使用中比较重要,据个人所知,很多用户往往将程序最小化后,不是将他最大化继续使用,而是重新打开了桌面上的快捷方式,结果很容易使程序2次运行时,导致内部变量或表等、重复使用或同时操作而极易出错,并误认为咱们的程序有毛病。
2、判定一个程序是否已经运行,个人认为,大家的见解水平都很高,值得学习。看来有2种方法。1)程序开始运行就让他创建一个文件或文件夹。程序结束时删除它。但是,当重复运行时,或遇到不正常退出的情况,再次运行程序时,需要人工判断和处理。2)API 方法。能够在同样的情况下,有自动识别的功能。这是他的优点之处。虽然系统版本有点影响,但是从前流行的window 系统来看,影响小得多。所以,开发者只能视其具体请情况而采用那种方式了。
谢谢!
2011-07-27 21:42
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 26楼 qingfameng
看過API中CreateFileMapping的工作原理嗎?那叫建立内存映射文件,即是在内存交換頁上建立文件作爲進程之間的公共數據區,其工作原理仍然是在磁盤上建立文件。知道這點就知道它與在磁盤直接建立文件檢測沒有什麽不同,反而更複雜。最開始那種檢測進程號的辦法是完全行不通的,後面的内存映射文件法可以用,但仍然要求正確釋放這個文件句柄。在32位和64位系統上,Windows供給的靜態内存頁地址未必一樣,何況這種方法無法移植到Mac機器上(VFP有Mac版本),這就是過分依賴系統的特殊功能。能夠用VFP自身語言解決的事,動輒調用系統指令,這種做法不值得提倡。很多習慣寫C程序的程序員,會有這種嗜好,但歷史經驗已經給過我們這種教訓,C程序員不好好用int類型的聲明,自以爲聰明地搞移位運算進行乘除法,結果微軟把int從2字節變爲4字節的時候,這些代碼全部要重新編寫,花費時間事少,遺漏修改帶來的隱患反大。

當然我這也是建議而已。

[ 本帖最后由 TonyDeng 于 2011-7-27 22:40 编辑 ]

授人以渔,不授人以鱼。
2011-07-27 22:32
qingfameng
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:35
帖 子:964
专家分:3019
注 册:2010-2-6
收藏
得分:0 
回复:27楼:
Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As SECURITY_ATTRIBUTES, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
并且注意:0xFFFFFFFF 看看与磁盘物理文件有什么不同? 说得不对请原谅!
 
2011-07-27 23:05
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
自己去查MSDN中CreateFileMapping函數的機制吧,不然弄本《Windows核心編程》看看,看看人家是怎麽運用這個函數的,而上面那個代碼又是怎麽做的。一知半解害死人!

授人以渔,不授人以鱼。
2011-07-27 23:39
寻H不得
Rank: 4
等 级:业余侠客
威 望:1
帖 子:181
专家分:222
注 册:2010-10-9
收藏
得分:0 
嘿 不管咋说 四楼的办法行得通 程序简单可行 顶一个
2011-07-29 20:40
快速回复:这样防止已经运行的程序再次运行?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019436 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved