且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

快速的方法来检查特定的进程在运行

更新时间:2023-11-25 11:05:22

在很多研究(从TeamViewer支持)我张贴一个明确的答案回应,希望帮助他人。代码是在Delphi中,但可以很容易地转换为C ++。

After much research (and a response from TeamViewer support) I am posting a definitive answer, hope it helpful to others. Code is in Delphi but can be translated easily to C++.

*如果您有没有信息关于过程的内部*

function IsRemoteSupportRunning() : Boolean;
var
    hSnapShot, hProcess: THandle;
    process: TProcessEntry32;
    bFound: Boolean;
begin
    bFound := False;
    if (cache.dwTeamViewerID = 0) then
        begin
        // TeamViewer not running...is it running now?
        try
            hSnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
            process.dwSize := Sizeof(TProcessEntry32);
            if (Process32First(hSnapShot, process)) then
                bFound := (AnsiCompareText(REMOTE_SUPPORT_EXE, process.szExeFile) = 0);

            if (not bFound) then
                begin
                while (Process32Next(hSnapShot, process)) do
                    begin
                    bFound := (AnsiCompareText(REMOTE_SUPPORT_EXE, process.szExeFile) = 0);
                    if (bFound) then
                        break;
                    end;
                end;

            CloseHandle(hSnapShot);
        except
        end;

        // If found, save the process ID
        if (bFound) then
            cache.dwTeamViewerID := process.th32ProcessID;
        end
    else
        begin
        // In a previous call to this function, TeamViewer was running...
        hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, cache.dwTeamViewerID);
        if (hProcess > 0) then
            begin
            // Still running!
            bFound := True;
            CloseHandle(hProcess);
            end
        else
            begin
            // Process is no longer running
            cache.dwTeamViewerID := 0;
            end;
        end;

    Result := bFound;
end;

在我的机器上,这会消耗〜1.5毫秒,如果TeamViewer.exe没有运行。一旦运行,PID是已知的,这种下降到〜6.8μs。

On my machine, this consumes ~1.5ms if TeamViewer.exe is not running. Once running and the PID is known, this drops to ~6.8µs.

*如果你有一些信息,亦或是拥有控制权,这个过程*

* IF YOU HAVE SOME INFO ABOUT, OR HAVE CONTROL OVER, THE PROCESS *

有多种可能性这里。例如,这个过程可能会创建(或你的代码的过程中创建)使用此代码共享内存对象:

There are a number of possibilities here. For example, the process may create (or you code the process to create) a shared memory object using this code:

CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MyProcess');

您现在可以通过使用此检查过程中运行:

You can now check for the process running by using this:

var
    hMapping: HWND;

hMapping := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MyProcess');
if (hMapping <> 0) then
    begin
    if (GetLastError() = ERROR_ALREADY_EXISTS) then
        bRunning := True;

    CloseHandle(hMapping);
    end;



最后,TeamViewer支持通知我关于命名的互斥体对象,你会在下面的代码中看到。请注意,这是特定于TeamViewer,但如果你有控制权的过程中,你可以创建一个互斥体,并使用这种技术。在我的系统,消耗了〜2.6μs

Finally, TeamViewer support informed me about a named mutex object which you'll see in the code below. Note that this is specific to TeamViewer, but if you had control over the process, you could create a mutex and use this technique. On my system, this consumes ~2.6µs!

function IsRemoteSupportRunning() : Boolean;
var
    hProcess: THandle;
begin
    // Use OpenMutex to see if TeamViewer.exe is running...
    Result := False;
    hProcess := OpenMutex(MUTEX_ALL_ACCESS, False, PChar('TeamViewer_Win32_Instance_Mutex'));
    if (hProcess > 0) then
        begin
        bFound := True;
        CloseHandle(hProcess);
        end;
end;



TeamViewer告诉我一个强大的工具WinObj调查系统中的对象的,的 https://technet.microsoft.com/de-de/sysinternals/bb896657.aspx 。退房的BaseNamedObjects。互斥显示为突变。

TeamViewer informed me of a powerful tool WinObj to investigate objects in the system, https://technet.microsoft.com/de-de/sysinternals/bb896657.aspx. Check out the BaseNamedObjects. Mutexes appear as "Mutant".