防止程序多重启动
2009-10-12 09:36:37 来源:WEB开发网此文章是接续怜香的"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,第二个以上的实例则以此键为"互斥对象"。还有往注册表中写一个键,方法和上面是一样的。
更多精彩
赞助商链接