WEB开发网
开发学院软件开发汇编语言 防止程序多重启动 阅读

防止程序多重启动

 2009-10-12 09:36:37 来源:WEB开发网   
核心提示:此文章是接续怜香的"DOS到Win32"系列教程第14篇的后续,阅读之前推荐查看前续文章正如怜香所说,命令行参数在Windows中是无处不在的,防止程序多重启动,只是一般感觉不到,双击一个txt文件,第二个以上的实例则以此键为"互斥对象",还有往注册表中写一个键,Windows会

此文章是接续怜香的"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,第二个以上的实例则以此键为"互斥对象"。还有往注册表中写一个键,方法和上面是一样的。

Tags:防止 程序 多重

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接