保证系统中只运行当前程序的一个进程

来源:互联网 发布:js break跳出几层循环 编辑:程序博客网 时间:2024/04/30 04:56
在学习代码的过程中,遇到了这样一个问题:一个程序,在需求上只允许产生一个进程,即不可重复运行,于是就产生了如何保证系统中只有一个进程存在的问题。这个问题网上的代码很多,不过都是一个解决办法,就是当程序二次运行的时候,如果发现系统中已经存在进程,则退出运行。不过我做的练习想实现另一种保持单例的方法,就是每次运行都杀掉那个老的进程,让新进程生成,虽然这个做法似乎通用性不好,不过在一些特殊情况还是有用的,比如我这个练习  ^_^

还是先写一下那比较常见的办法,蛮简单:
uses    //uses这里不知道是不是引用了多余的东西,呵呵,没检查~
  Windows, Messages, SysUtils, Dialogs;
var
  FormHandle : THandle;
begin
  FormHandle := windows.OpenMutex(MUTEX_ALL_ACCESS,false,'test');   //这里的test似乎是可以随便写的
  if FormHandle <> 0 then
  begin
    ShowMessage('程序已经运行');
  end
  else
  begin
    windows.CreateMutex(nil,false,'test');    ////这里的test和上面那个要一致,这是对这程序的标识
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;
end.

注意:这种处理方法的例子很多,写法也有不少,我这个是最基本的方法,应该是不大严谨,不过倒是好用,嘻嘻

下面是我费了好大劲想出来的,杀掉旧进程的做法:
uses
  Windows, Messages, SysUtils, Forms, Dialogs, tlhelp32;
var
  FormHandle : THandle;
  hand:thandle;
  lppe:PROCESSENTRY32;
  found:boolean;
begin
  Hand:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);    //这句,不懂,看来的,嘎嘎
  if hand>0 then
    lppe.dwSize:= sizeof(PROCESSENTRY32);    //初始化,没啥特别的
  FormHandle := windows.OpenMutex(MUTEX_ALL_ACCESS,false,'test');   //这里和上面一样啦
  if FormHandle <> 0 then
  begin
    found:=Process32First(Hand,lppe);   //开始遍历进程列表啦
    while found do
    begin
      if strpas(lppe.szExeFile) = ExtractFileName(Application.ExeName) then   //判断是否是当前程序的进程
      begin
         //下面这句是终止这个进程
        TerminateProcess(OpenProcess(PROCESS_ALL_ACCESS,FALSE,lppe.th32ProcessID),1);
        break;   //这句是必须的,因为新进程已经生成,所以同名进程有两个,杀掉旧的就跳出循环了
                      //不然连新的一起杀掉了,所谓见好就收哇
      end;
      found:=Process32next(Hand,lppe);
    end;
  end
  else
  begin
    windows.CreateMutex(nil,false,'test');   //这里也是
  end;
  Application.Initialize;    //这里不同,是把它们拿到判断语句外面了,因为杀掉旧进程,新进程要运行嘛
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

注意:这里用到的思路是遍历了进程列表,获得旧进程,并杀掉。曾经担心新进程会不会跑到进程列表前面去,不过在后来的测试中感觉进程列表应该是顺序添加的,所以新进程应该是在列表的后面的,至少我目前是这个情况嘎。
原创粉丝点击