操作系统  办公  实用知识  设计  开发  WEB开发  移动开发  数据库  软件工程  网管  安全  管理  信息化  答疑  渠道 

防止程序多重启动

2006-9-29 网友评论 0 条 点击进入论坛

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

已有 0 位对此文章感兴趣的网友发布了看法    
我来评两句 登录邮箱: 密码:
  匿名发表
今日推荐
技术文库(共有 46732 篇文章)
操作系统
办公软件
实用知识
网络管理
软件开发
WEB开发
软件工程
数据库
设计在线
信息安全
行业信息化
管理信息化
重点推荐
电子杂志订阅
点击电子杂志名称查看样刊
输入E-mail地址即可订阅
E-mail