比如说我要知道电脑里是否有qq在运行,搜索进程列表,能得到进程名和进程id,然后根据进程名确定相关程序是否存在,如果有"qq.exe",就返回存在。但只要把QQ程序的名字改一下,那就无法确定了。
名字可以随便改不影响运行,但程序本身是不会变的,就比如说QQ程序,人家可以把名字随便给改了,但双击下去还是同样的界面,如何确定是否有QQ正在运行?我们是一个第三方的程序,不可以挂dll在QQ程序里,不能修改QQ程序本身,一开始也不知道QQ安装在哪,可以通过进程列表查找QQ路径,但首先要知道哪个进程是QQ(不可以在首次运行时人为指定QQ的路径,全自动化,一切由程序自己解决)。

解决方案 »

  1.   

    可以通过文件的版本信息确定
    参考如下代码
    uses PsAPI, TlHelp32;type
      TFileVersionInfomation = record // 文件版本信息
        rCommpanyName: string;
        rFileDescription: string;
        rFileVersion: string;
        rInternalName: string;
        rLegalCopyright: string;
        rLegalTrades: string;
        rOriginalFileName: string;
        rProductName: string;
        rProductVersion: string;
        rComments: string;
        rVsFixedFileInfo: VS_FIXEDFILEINFO;
        rDefineValue: string;
      end;function GetFileVersionInfomation( // 读取文件的版本信息
      mFileName: string; // 目标文件名
      var nFileVersionInfomation: TFileVersionInfomation; // 文件信息结构
      mDefineName: string = '' // 自定义字段名
    ): Boolean; // 返回是否读取成功
    var
      vHandle: Cardinal;
      vInfoSize: Cardinal;
      vVersionInfo: Pointer;
      vTranslation: Pointer;
      vVersionValue: string;
      vInfoPointer: Pointer;
    begin
      Result := False;
      vInfoSize := GetFileVersionInfoSize(PChar(mFileName), vHandle); // 取得文件版本信息空间及资源句柄
      FillChar(nFileVersionInfomation, SizeOf(nFileVersionInfomation), 0); // 初始化返回信息
      if vInfoSize <= 0 then Exit; // 安全检查  GetMem(vVersionInfo, vInfoSize); // 分配资源
      with nFileVersionInfomation do try
        if not GetFileVersionInfo(PChar(mFileName),
          vHandle, vInfoSize, vVersionInfo) then Exit;
        CloseHandle(vHandle);
        VerQueryValue(vVersionInfo, '\VarFileInfo\Translation',
          vTranslation, vInfoSize);
        if not Assigned(vTranslation) then Exit;
        vVersionValue := Format('\StringFileInfo\%.4x%.4x\',
          [LOWORD(Longint(vTranslation^)), HIWORD(Longint(vTranslation^))]);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'CompanyName'),
          vInfoPointer, vInfoSize);
        rCommpanyName := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'FileDescription'),
          vInfoPointer, vInfoSize);
        rFileDescription := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'FileVersion'),
          vInfoPointer, vInfoSize);
        rFileVersion := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'InternalName'),
          vInfoPointer, vInfoSize);
        rInternalName := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'LegalCopyright'),
          vInfoPointer, vInfoSize);
        rLegalCopyright := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'LegalTrades'),
          vInfoPointer, vInfoSize);
        rLegalTrades := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'OriginalFileName'),
          vInfoPointer, vInfoSize);
        rOriginalFileName := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'ProductName'),
          vInfoPointer, vInfoSize);
        rProductName := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'ProductVersion'),
          vInfoPointer, vInfoSize);
        rProductVersion := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, PChar(vVersionValue + 'Comments'),
          vInfoPointer, vInfoSize);
        rComments := PChar(vInfoPointer);
        VerQueryValue(vVersionInfo, '\', vInfoPointer, vInfoSize);
        rVsFixedFileInfo := TVSFixedFileInfo(vInfoPointer^);
        if mDefineName <> '' then begin
          VerQueryValue(vVersionInfo, PChar(vVersionValue + mDefineName),
            vInfoPointer, vInfoSize);
          rDefineValue := PChar(vInfoPointer);
        end else rDefineValue := '';
      finally
        FreeMem(vVersionInfo, vInfoSize);
      end;
      Result := True;
    end; { GetFileVersionInfomation }procedure TForm1.Button1Click(Sender: TObject);
    var
      vSnapshot: THandle;
      vProcessEntry32: TProcessEntry32;
      vProcess: THandle;
      vBuffer: array[0..MAX_PATH] of Char;
      L: Integer;
      vHandle: THandle;
      vFileVersionInfomation: TFileVersionInfomation;
    begin
      vSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      vProcessEntry32.dwSize := SizeOf(TProcessEntry32);
      Process32First(vSnapshot, vProcessEntry32);
      repeat
        if vProcessEntry32.th32ProcessID <> 0 then
        begin
          vProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
            False, vProcessEntry32.th32ProcessID);
          try
            L := GetModuleFileNameEx(vProcess, 0, vBuffer, SizeOf(vBuffer));
            if (L > 0) and
              GetFileVersionInfomation(vBuffer, vFileVersionInfomation) and
              SameText(vFileVersionInfomation.rOriginalFileName, 'QQ.exe') then
            begin
              ShowMessage(Format('QQ已经启动, 进程ID:%d', [vProcessEntry32.th32ProcessID]));
            end;
          finally
            CloseHandle(vProcess);
          end;
        end;
      until not Process32Next(vSnapshot, vProcessEntry32);
      CloseHandle(vSnapshot);
    end;
    也可以更加所在的目录dll文件加强判断。