Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查特定进程是否正在运行的快速方法_C#_C++_Windows_Delphi - Fatal编程技术网

C# 检查特定进程是否正在运行的快速方法

C# 检查特定进程是否正在运行的快速方法,c#,c++,windows,delphi,C#,C++,Windows,Delphi,要检查进程是否正在运行,可以使用“CreateToolHelp32SnapShot”Windows API函数并枚举正在运行的进程。答案问题中给出了示例C/C++代码: 我的问题是,如果您知道您正在寻找一个特定的流程,是否有一种更快的方法来找到答案,而不必依次检查每个流程?我们需要定期检查远程支持工具TeamViewer.exe是否正在运行。请注意,TeamViewer是由第三方编写的,我们无法控制它或了解EXE的内部结构 编辑: TeamViewer提供了一些有关其流程内部的信息,这些信息可

要检查进程是否正在运行,可以使用“CreateToolHelp32SnapShot”Windows API函数并枚举正在运行的进程。答案问题中给出了示例C/C++代码:

我的问题是,如果您知道您正在寻找一个特定的流程,是否有一种更快的方法来找到答案,而不必依次检查每个流程?我们需要定期检查远程支持工具TeamViewer.exe是否正在运行。请注意,TeamViewer是由第三方编写的,我们无法控制它或了解EXE的内部结构

编辑:


TeamViewer提供了一些有关其流程内部的信息,这些信息可用于在此实例中加速此过程(请参阅已接受的答案)。答案还显示了如何加快任何进程的检查速度(通过保存进程ID)。

必须采取的第一步是枚举进程。使用toolhelp或
枚举进程
执行此操作。如果找到进程,请将PID传递到
OpenProcess
,以获取进程句柄。然后等待进程发出信号。这样,除了初始枚举之外,就无需进行轮询


如果初始枚举未能找到进程,则必须重复枚举。使用工具帮助或
enumProcesss
中证明更有效的一种。也许会限制投票。您也可以选择使用WMI来通知新进程的创建,这样就完全避免了轮询的需要

必须采取的第一步是枚举进程。使用toolhelp或
枚举进程
执行此操作。如果找到进程,请将PID传递到
OpenProcess
,以获取进程句柄。然后等待进程发出信号。这样,除了初始枚举之外,就无需进行轮询

如果初始枚举未能找到进程,则必须重复枚举。使用工具帮助或
enumProcesss
中证明更有效的一种。也许会限制投票。您也可以选择使用WMI来通知新进程的创建,这样就完全避免了轮询的需要

经过大量研究(以及TeamViewer支持部门的回复),我发布了一个明确的答案,希望对其他人有所帮助。代码在Delphi中,但是可以很容易地翻译成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;
在我的机器上,如果TeamViewer.exe未运行,这将消耗约1.5ms。一旦运行且PID已知,这将降至约6.8µs

*如果您对流程有一些信息或控制权*

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;
这里有许多可能性。例如,该进程可能会使用以下代码创建(或将该进程编码为创建)共享内存对象:

CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MyProcess');
现在,您可以使用以下命令检查正在运行的进程:

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告诉我有一个功能强大的工具WinObj来调查系统中的对象。查看BaseNamedObjects。互斥体显示为“突变体”。

经过大量研究(以及TeamViewer支持部门的回复),我发布了一个明确的答案,希望对其他人有所帮助。代码在Delphi中,但是可以很容易地翻译成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;
在我的机器上,如果TeamViewer.exe未运行,这将消耗约1.5ms。一旦运行且PID已知,这将降至约6.8µs

*如果您对流程有一些信息或控制权*

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;
这里有许多可能性。例如,该进程可能会使用以下代码创建(或将该进程编码为创建)共享内存对象:

CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READONLY, 0, 32, 'MyProcess');
现在,您可以使用以下命令检查正在运行的进程:

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告诉我有一个功能强大的工具WinObj来调查系统中的对象。查看BaseNamedObjects。互斥锁显示为“突变体”。

在Windows上,您可以利用
system()
\u wsystem()
快速确定进程是否按名称运行。如果要发送包含的整个进程名
.exe
,只需从函数的第一行删除字符
.exe

static bool process_exists(std::wstring token)
{
    std::wstring cmd_query(std::wstring(L"tasklist|findstr /i \"") + token + L".exe\">nul 2>&1");
    return (_wsystem(cmd_query.data()) == 0) ? (true) : (false);
}

在Windows上,您可以利用
system()
\u wsystem()
快速确定进程是否按名称运行。如果要发送包含的整个进程名
.exe
,只需从函数的第一行删除字符
.exe

static bool process_exists(std::wstring token)
{
    std::wstring cmd_query(std::wstring(L"tasklist|findstr /i \"") + token + L".exe\">nul 2>&1");
    return (_wsystem(cmd_query.data()) == 0) ? (true) : (false);
}

使用互斥来检查正在运行的进程

在检查过程中创建具有特定名称的互斥体,并检查该互斥体是否存在于其他过程中

过程1:

        using var mutex = new Mutex(true, LockId, out var created);
LockId
是一个特定的名称

    public const string LockId = "5742D257-CCCC-4F7A-8191-6362609C458D";

进程2可用于检查互斥体是否存在

使用互斥来检查正在运行的进程

在检查过程中创建具有特定名称的互斥体,并检查该互斥体是否存在于其他过程中

过程1:

        using var mutex = new Mutex(true, LockId, out var created);
LockId
是一个特定的名称

    public const string LockId = "5742D257-CCCC-4F7A-8191-6362609C458D";

进程2可用于检查互斥体是否存在

通过某种
WaitForSingleObject
函数等待特定的进程句柄(当然,
WaitForMultipleObjects
更适合实数,因为它允许您中断等待)。枚举进程还有其他方法。但是,您能告诉我们您有哪些性能问题,以及您的性能限制是什么吗?另外,您是否致力于轮询?@David,我真的建议在这里使用Y而不是X(无论性能如何)。与其说此检查本身很慢(上面的代码通常在2-3ms内运行),还不如说它是“在要求很高的图像处理应用程序中发生的数百件事情之一”。这是在分析过程中出现的,可以从可能的加速中获益。当然,我们将考虑减慢投票速度(或完全放弃投票)以及其他一些问题