Status eines oder aller Prozesse herausfinden
Hallo alle zusammen!
Ich arbeite mit Visual Studio 2017 in C++ unter Windows 10.
Ich habe mir das Grundgerüst eines Programm geschrieben, aber da ich durch googeln nicht weiterkam, frage ich euch mal.
Nähmlich:
Ich würde gern wissen, welche(r) Prozess(e) diesen Status haben. (Mit "dieser" meine ich z.B.: Angehalten, Wird ausgeführt,...)
Als Beispiel:
Der Prozess ShellExperienceHost.exe ist immer gestartet unter dem Status "Angehalten", aber der Status ändert
sich zu "Wird ausgeführt", wenn man die Windowstaste drückt (Also das Menü aufpoppt).
Ich wäre froh, wenn es eine Möglichkeit gibt, von allen Prozessen die herauszupicken, die dem Status X entsprechen und dann z.B.: diese zu beenden oder anzuzeigen.
Aber ich kann auch, wie im Beispiel, einen Prozess auswählen und dessen Status überprüfen.
Wenn möglich würde ich gerne keine externen Dateien verwenden.
LG,
tomaschku
Ich arbeite mit Visual Studio 2017 in C++ unter Windows 10.
Ich habe mir das Grundgerüst eines Programm geschrieben, aber da ich durch googeln nicht weiterkam, frage ich euch mal.
Nähmlich:
Ich würde gern wissen, welche(r) Prozess(e) diesen Status haben. (Mit "dieser" meine ich z.B.: Angehalten, Wird ausgeführt,...)
Als Beispiel:
Der Prozess ShellExperienceHost.exe ist immer gestartet unter dem Status "Angehalten", aber der Status ändert
sich zu "Wird ausgeführt", wenn man die Windowstaste drückt (Also das Menü aufpoppt).
Ich wäre froh, wenn es eine Möglichkeit gibt, von allen Prozessen die herauszupicken, die dem Status X entsprechen und dann z.B.: diese zu beenden oder anzuzeigen.
Aber ich kann auch, wie im Beispiel, einen Prozess auswählen und dessen Status überprüfen.
Wenn möglich würde ich gerne keine externen Dateien verwenden.
LG,
tomaschku
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 356910
Url: https://administrator.de/contentid/356910
Ausgedruckt am: 21.11.2024 um 23:11 Uhr
14 Kommentare
Neuester Kommentar
Folgende Win32 Funktion sollte dir weiterhelfen
https://msdn.microsoft.com/en-us/library/windows/desktop/hh448381(v=vs.8 ...
Enthalten in "windows.h"
For-Schleife über alle Prozesse und Status checken.
https://msdn.microsoft.com/en-us/library/windows/desktop/hh448381(v=vs.8 ...
Enthalten in "windows.h"
For-Schleife über alle Prozesse und Status checken.
Geht per NtQuerySystemInformation. Wie genau, muss ich mich auch erst einlesen. (Vielleicht habe ich heute Abend etwas Zeit.) Ganz so einfach wird das nicht, denn grundsätzlich kann ein Prozess bspw. nicht suspended sein, alle seine Threads aber shon, was dann zum Ergebnis hat dass der Prozess quasi "angehalten" ist. NtQuerySystemInformation liefert auch die Informationen zu den einzelnen Threads eines Prozesses, die Verarbeitung ist aber (wie immer bei der WinAPI) eher C-Style und nicht gerade schön...
Steffen
Steffen
Schau mal hier rein
https://stackoverflow.com/questions/22949725/how-to-get-thread-state-e-g ...
https://stackoverflow.com/questions/22949725/how-to-get-thread-state-e-g ...
Nur für die Powershell-Fraktion, ein Oneliner:
get-Process | select Name,@{n='State';e={$_.Threads.Threadstate | select -Unique}},@{n='Reason';e={$_.Threads.WaitReason | select -Unique}} | ?{$_.Name -ne 'System' -and $_.State -contains 'Wait' -and $_.Reason -contains 'Suspended'}
Schau mal ob das mit VS läuft. Konnte nur mit MinGW testen.
Steffen
EDIT Update Type-Casts für 64Bit Prozessoren
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x0600
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <winternl.h>
#include <ntstatus.h>
struct proc_info
{
std::wstring name;
unsigned process_id;
bool suspended;
};
using process_vector = std::vector<proc_info>;
struct process_state
{
process_state();
~process_state() noexcept;
void update();
process_vector get_suspended() const;
void print() const;
private:
process_vector m_proc_infos;
void get();
};
int main(int argc, char* argv)
{
std::wcout << L"~~~~~~~~ All:\n";
process_state p_state;
p_state.print();
std::wcout << L"~~~~~~~~ Suspended:\n";
process_vector susp{p_state.get_suspended()};
for (const auto& elem : susp)
std::wcout << elem.name << L'\t' << elem.process_id << std::endl;
return 0;
}
typedef NTSTATUS (WINAPI *tNTQSI)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
process_state::process_state()
{
get();
}
process_state::~process_state() noexcept
{
}
void process_state::update()
{
get();
}
process_vector process_state::get_suspended() const
{
process_vector susp;
for (const auto& elem : m_proc_infos)
{
if (elem.suspended)
susp.push_back(elem);
}
return susp;
}
void process_state::print() const
{
const std::ios_base::fmtflags former_flags{std::wcout.flags()};
std::wcout << std::boolalpha;
for (const auto& elem : m_proc_infos)
{
std::wcout << elem.name << L'\n'
<< L"Process ID: " << elem.process_id << L'\n'
<< L"Suspended: " << elem.suspended << L'\n' << std::endl;
}
std::wcout.flags(former_flags);
}
void process_state::get()
{
m_proc_infos.clear();
tNTQSI fpNTQSI{reinterpret_cast<tNTQSI>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation"))};
if (fpNTQSI == NULL)
throw std::runtime_error{"function NtQuerySystemInformation not found"};
HANDLE hHeap{GetProcessHeap()};
ULONG cbBuffer{1048576UL};
LPVOID pBuffer{};
if ((pBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBuffer)) == NULL)
throw std::runtime_error{"bad memory allocation"};
if (fpNTQSI(SystemProcessInformation, pBuffer, cbBuffer, &cbBuffer) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(hHeap, 0, pBuffer);
throw std::runtime_error{"insufficient memory allocated"};
}
PSYSTEM_PROCESS_INFORMATION pProc{reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(pBuffer)};
for (;;)
{
if (reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId) > static_cast<ULONG_PTR>(4UL))
{
m_proc_infos.push_back({std::wstring{pProc->ImageName.Buffer, static_cast<size_t>(pProc->ImageName.Length)}.c_str(), static_cast<unsigned>(reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId)), false});
PSYSTEM_THREADS pThreads{reinterpret_cast<PSYSTEM_THREADS>(pProc + 1)};
for (ULONG i{}; i < pProc->NumberOfThreads; ++pThreads, ++i)
{
if (pThreads->State == StateWait && pThreads->WaitReason == Suspended)
{
m_proc_infos.back().suspended = true;
break;
}
}
}
if (pProc->NextEntryOffset == 0UL)
break;
pProc = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>((reinterpret_cast<LPBYTE>(pProc)) + pProc->NextEntryOffset);
}
HeapFree(hHeap, 0, pBuffer);
}
EDIT Update Type-Casts für 64Bit Prozessoren
Hmm. Dann machen wir die Deklarationen eben wieder von Hand.
Steffen
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdexcept>
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x0600
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
struct proc_info
{
std::wstring name;
unsigned process_id;
bool suspended;
};
using process_vector = std::vector<proc_info>;
struct process_state
{
process_state();
~process_state() noexcept;
void update();
process_vector get_suspended() const;
void print() const;
private:
process_vector m_proc_infos;
void get();
};
int main(int argc, char* argv)
{
std::wcout << L"~~~~~~~~ All:\n";
process_state p_state;
p_state.print();
std::wcout << L"~~~~~~~~ Suspended:\n";
process_vector susp{p_state.get_suspended()};
for (const auto& elem : susp)
std::wcout << elem.name << L'\t' << elem.process_id << std::endl;
return 0;
}
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation = 0,
SystemProcessorInformation = 1,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemProcessInformation = 5,
SystemProcessorPerformanceInformation = 8,
SystemHandleInformation = 16,
SystemPagefileInformation = 18,
SystemInterruptInformation = 23,
SystemExceptionInformation = 33,
SystemRegistryQuotaInformation = 37,
SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;
typedef enum _THREAD_STATE {
StateInitialized = 0,
StateReady, StateRunning, StateStandby, StateTerminated,
StateWait, StateTransition,
StateUnknown
} THREAD_STATE;
typedef enum _KWAIT_REASON {
Executive = 0,
FreePage, PageIn, PoolAllocation, DelayExecution,
Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn,
WrPoolAllocation, WrDelayExecution, WrSuspended,
WrUserRequest, WrEventPair, WrQueue, WrLpcReceive,
WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous,
Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel,
MaximumWaitReason
} KWAIT_REASON;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef LONG KPRIORITY;
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS, *PVM_COUNTERS;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG PageDirectoryBase;
VM_COUNTERS VirtualMemoryCounters;
SIZE_T PrivatePageCount;
IO_COUNTERS IoCounters;
} SYSTEM_PROCESS_INFORMATION,*PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef NTSTATUS (WINAPI *tNTQSI)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
process_state::process_state()
{
get();
}
process_state::~process_state() noexcept
{
}
void process_state::update()
{
get();
}
process_vector process_state::get_suspended() const
{
process_vector susp;
for (const auto& elem : m_proc_infos)
{
if (elem.suspended)
susp.push_back(elem);
}
return susp;
}
void process_state::print() const
{
const std::ios_base::fmtflags former_flags{std::wcout.flags()};
std::wcout << std::boolalpha;
for (const auto& elem : m_proc_infos)
{
std::wcout << elem.name << L'\n'
<< L"Process ID: " << elem.process_id << L'\n'
<< L"Suspended: " << elem.suspended << L'\n' << std::endl;
}
std::wcout.flags(former_flags);
}
void process_state::get()
{
m_proc_infos.clear();
tNTQSI fpNTQSI{reinterpret_cast<tNTQSI>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation"))};
if (fpNTQSI == NULL)
throw std::runtime_error{"function NtQuerySystemInformation not found"};
HANDLE hHeap{GetProcessHeap()};
ULONG cbBuffer{1048576UL};
LPVOID pBuffer{};
if ((pBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBuffer)) == NULL)
throw std::runtime_error{"bad memory allocation"};
if (fpNTQSI(SystemProcessInformation, pBuffer, cbBuffer, &cbBuffer) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(hHeap, 0, pBuffer);
throw std::runtime_error{"insufficient memory allocated"};
}
PSYSTEM_PROCESS_INFORMATION pProc{reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(pBuffer)};
for (;;)
{
if (reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId) > static_cast<ULONG_PTR>(4UL))
{
m_proc_infos.push_back({std::wstring{pProc->ImageName.Buffer, static_cast<size_t>(pProc->ImageName.Length)}.c_str(), static_cast<unsigned>(reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId)), false});
PSYSTEM_THREADS pThreads{reinterpret_cast<PSYSTEM_THREADS>(pProc + 1)};
for (ULONG i{}; i < pProc->NumberOfThreads; ++pThreads, ++i)
{
if (pThreads->State == StateWait && pThreads->WaitReason == Suspended)
{
m_proc_infos.back().suspended = true;
break;
}
}
}
if (pProc->NextEntryOffset == 0UL)
break;
pProc = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>((reinterpret_cast<LPBYTE>(pProc)) + pProc->NextEntryOffset);
}
HeapFree(hHeap, 0, pBuffer);
std::sort(m_proc_infos.begin(), m_proc_infos.end(), (const auto& a, const auto& b) { return lstrcmpiW(a.name.c_str(), b.name.c_str()) < 0; });
}
(EDIT Während du geantwortet hast, war ich noch am Verfassen dieses Posts. Hoffe es hilft trotzdem noch ...)
Mittlerweile konnte ich auch mit VS testen. Rennt. Weil mein ...
... von oben maßlos untertrieben war, macht es wohl Sinn den ganze WinAPI Mist auszulagern und ein bisschen Struktur rein zu bringen. Auf diese Weise wird dein Hauptcode wieder übersichtlich und du kannst dort sauberes C++ schreiben. Der unschöne Code ist dann in der Implementierung (was üblicherweise auch in anderen Bibliotheken der Fall ist). Die typedef enums und typedef structs in der Implementierung entstammen der winternl.h von mingw-w64 und sind ohne Copyright in der Public Domain veröffentlicht. Somit ist die Verwendung hier problemlos möglich.
process_state.h
process_state.cpp
Beide Dateien fügst du deinem Projekt hinzu und includierst "process_state.h". Im Header-Code habe ich ein paar Kommentare hinterlassen. Wie du siehst habe ich noch ein paar Memberfunktionen hinzugefügt, sowie eine Funktion zum Killen eines Prozesses per Prozess ID, was eine deiner fett gedruckten Anforderungen war.
Zum Testen:
Steffen
Mittlerweile konnte ich auch mit VS testen. Rennt. Weil mein ...
... von oben maßlos untertrieben war, macht es wohl Sinn den ganze WinAPI Mist auszulagern und ein bisschen Struktur rein zu bringen. Auf diese Weise wird dein Hauptcode wieder übersichtlich und du kannst dort sauberes C++ schreiben. Der unschöne Code ist dann in der Implementierung (was üblicherweise auch in anderen Bibliotheken der Fall ist). Die typedef enums und typedef structs in der Implementierung entstammen der winternl.h von mingw-w64 und sind ohne Copyright in der Public Domain veröffentlicht. Somit ist die Verwendung hier problemlos möglich.
process_state.h
#ifndef PROCESS_STATE_H_INCLUDED__
#define PROCESS_STATE_H_INCLUDED__
#include <string>
#include <vector>
// member type of the process_vector
struct proc_info
{
std::wstring name; // process name
unsigned process_id; // process ID
bool suspended; // true if at least one of the threads of the process was suspended
};
using process_vector = std::vector<proc_info>;
struct process_state
{
// constructor, during construction proc_info data of all currently running processes will be collected
process_state();
// destructor
~process_state() noexcept;
// update proc_info data of all currently running processes
void update();
// return a copy of the collected data, sorted by name
process_vector get_all() const;
// return the collected data of all suspended processes, sorted by name
process_vector get_suspended() const;
// return the collected data of all not-suspended processes, sorted by name
process_vector get_not_suspended() const;
// return the collected data of all processes with the specified name (not case-sensitive)
process_vector get_by_name(const std::wstring& name) const;
// return the collected data of processes with with the specified name (not case-sensitive) in the specified vector
process_vector get_by_name(const std::wstring& name, const process_vector& p_info) const;
// return the collected data of all processes with the specified process ID
process_vector get_by_id(const unsigned& process_id) const;
// return the collected data of processes with the specified process ID in the specified vector
process_vector get_by_id(const unsigned& process_id, const process_vector& p_info) const;
// print the collected data, sorted by name
void print() const;
// print the collected data in the specified vector
void print(const process_vector& p_info) const;
private:
process_vector m_proc_infos;
void get();
};
// terminate the process with the specified process ID
bool terminate_process(const unsigned& process_id);
#endif // PROCESS_STATE_H_INCLUDED__
process_state.cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include "process_state.h"
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#ifdef WINVER
#undef WINVER
#endif
#define WINVER 0x0600
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation = 0,
SystemProcessorInformation = 1,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemProcessInformation = 5,
SystemProcessorPerformanceInformation = 8,
SystemHandleInformation = 16,
SystemPagefileInformation = 18,
SystemInterruptInformation = 23,
SystemExceptionInformation = 33,
SystemRegistryQuotaInformation = 37,
SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;
typedef enum _THREAD_STATE
{
StateInitialized = 0,
StateReady, StateRunning, StateStandby, StateTerminated,
StateWait, StateTransition,
StateUnknown
} THREAD_STATE;
typedef enum _KWAIT_REASON
{
Executive = 0,
FreePage, PageIn, PoolAllocation, DelayExecution,
Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn,
WrPoolAllocation, WrDelayExecution, WrSuspended,
WrUserRequest, WrEventPair, WrQueue, WrLpcReceive,
WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous,
Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel,
MaximumWaitReason
} KWAIT_REASON;
typedef LONG KPRIORITY;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _VM_COUNTERS
{
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS, *PVM_COUNTERS;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG PageDirectoryBase;
VM_COUNTERS VirtualMemoryCounters;
SIZE_T PrivatePageCount;
IO_COUNTERS IoCounters;
} SYSTEM_PROCESS_INFORMATION,*PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef NTSTATUS (WINAPI *tNTQSI)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
process_state::process_state()
{
get();
}
process_state::~process_state() noexcept
{
}
void process_state::update()
{
get();
}
process_vector process_state::get_all() const
{
return m_proc_infos;
}
process_vector process_state::get_suspended() const
{
process_vector susp;
for (const auto& elem : m_proc_infos)
{
if (elem.suspended)
susp.push_back(elem);
}
return susp;
}
process_vector process_state::get_not_suspended() const
{
process_vector nsusp;
for (const auto& elem : m_proc_infos)
{
if (!elem.suspended)
nsusp.push_back(elem);
}
return nsusp;
}
process_vector process_state::get_by_name(const std::wstring& name) const
{
return get_by_name(name, m_proc_infos);
}
process_vector process_state::get_by_name(const std::wstring& name, const process_vector& p_info) const
{
process_vector collected;
auto it{p_info.cbegin()}, found{p_info.cend()};
do
{
found = std::find_if(it, p_info.cend(), [name](const auto& elem) { return lstrcmpiW(elem.name.c_str(), name.c_str()) == 0; });
if (found != p_info.cend())
{
collected.push_back(*found);
it = ++found;
}
} while (found != p_info.cend());
return collected;
}
process_vector process_state::get_by_id(const unsigned& process_id) const
{
return get_by_id(process_id, m_proc_infos);
}
process_vector process_state::get_by_id(const unsigned& process_id, const process_vector& p_info) const
{
process_vector collected;
auto found{std::find_if(p_info.cbegin(), p_info.cend(), [process_id](const auto& elem) { return elem.process_id == process_id; })};
if (found != p_info.cend())
collected.push_back(*found);
return collected;
}
void process_state::print() const
{
print(m_proc_infos);
}
void process_state::print(const process_vector& p_info) const
{
const std::ios_base::fmtflags former_flags{std::wcout.flags()};
std::wcout << std::boolalpha;
for (const auto& elem : p_info)
{
std::wcout << elem.name << L'\n'
<< L"Process ID: " << elem.process_id << L'\n'
<< L"Suspended: " << elem.suspended << L'\n' << std::endl;
}
std::wcout.flags(former_flags);
}
void process_state::get()
{
m_proc_infos.clear();
tNTQSI fpNTQSI{reinterpret_cast<tNTQSI>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation"))};
if (fpNTQSI == NULL)
throw std::runtime_error{"function NtQuerySystemInformation not found"};
HANDLE hHeap{GetProcessHeap()};
ULONG cbBuffer{1048576UL};
LPVOID pBuffer{};
if ((pBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbBuffer)) == NULL)
throw std::runtime_error{"bad memory allocation"};
if (fpNTQSI(SystemProcessInformation, pBuffer, cbBuffer, &cbBuffer) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(hHeap, 0, pBuffer);
throw std::runtime_error{"insufficient memory allocated"};
}
PSYSTEM_PROCESS_INFORMATION pProc{reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(pBuffer)};
for (;;)
{
if (reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId) > static_cast<ULONG_PTR>(4UL))
{
m_proc_infos.push_back({std::wstring{pProc->ImageName.Buffer, static_cast<size_t>(pProc->ImageName.Length)}.c_str(), static_cast<unsigned>(reinterpret_cast<ULONG_PTR>(pProc->UniqueProcessId)), false});
PSYSTEM_THREADS pThreads{reinterpret_cast<PSYSTEM_THREADS>(pProc + 1)};
for (ULONG i{}; i < pProc->NumberOfThreads; ++pThreads, ++i)
{
if (pThreads->State == StateWait && pThreads->WaitReason == Suspended)
{
m_proc_infos.back().suspended = true;
break;
}
}
}
if (pProc->NextEntryOffset == 0UL)
break;
pProc = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>((reinterpret_cast<LPBYTE>(pProc)) + pProc->NextEntryOffset);
}
HeapFree(hHeap, 0, pBuffer);
std::sort(m_proc_infos.begin(), m_proc_infos.end(), (const auto& a, const auto& b) { return lstrcmpiW(a.name.c_str(), b.name.c_str()) < 0; });
}
bool terminate_process(const unsigned& process_id)
{
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, process_id);
if (hProc == NULL)
return false;
BOOL ret = TerminateProcess(hProc, 0);
if (ret != FALSE)
WaitForSingleObject(hProc, INFINITE);
CloseHandle(hProc);
return ret != FALSE;
}
Beide Dateien fügst du deinem Projekt hinzu und includierst "process_state.h". Im Header-Code habe ich ein paar Kommentare hinterlassen. Wie du siehst habe ich noch ein paar Memberfunktionen hinzugefügt, sowie eine Funktion zum Killen eines Prozesses per Prozess ID, was eine deiner fett gedruckten Anforderungen war.
Zum Testen:
#include <iostream>
#include "process_state.h"
int main(int argc, char* argv)
{
process_state p_state;
std::wcout << L"\n~~~~~~~~ All: ~~~~~~~~~~~~~~~~~~\n";
p_state.print();
std::wcout << L"\n~~~~~~~~ Suspended: ~~~~~~~~~~~~\n";
p_state.print(p_state.get_suspended());
std::wcout << L"\n~~~~~~~~ Not Suspended: ~~~~~~~~\n";
p_state.print(p_state.get_not_suspended());
std::wcout << L"\n~~~~~~~~ Notepad processes: ~~~~~\n";
p_state.print(p_state.get_by_name(L"Notepad.exe"));
return 0;
}
Steffen
[OT]
Finde ich gut, dass du das nicht so hältst. Ich helfe gern, aber irgend ein Feedback (positiv oder negativ) erwarte ich schon...
Hehe, ja tatsächlich. Hatte VS bereits installiert, ist aber nicht mehr gelaufen, da sich mein Win10 seit dem Fall Creators Update selbst degeneriert. Regulär deinstallieren hat auch nicht funktioniert, sodass ich mich erst mal händisch durch Dateisystem und Registry kämpfen musste, bevor ich neu installieren konnte.
Hab bald Urlaub, dann mache ich die Kiste platt und setze Windows neu auf ...
Steffen
[/OT]
Finde ich gut, dass du das nicht so hältst. Ich helfe gern, aber irgend ein Feedback (positiv oder negativ) erwarte ich schon...
Hehe, ja tatsächlich. Hatte VS bereits installiert, ist aber nicht mehr gelaufen, da sich mein Win10 seit dem Fall Creators Update selbst degeneriert. Regulär deinstallieren hat auch nicht funktioniert, sodass ich mich erst mal händisch durch Dateisystem und Registry kämpfen musste, bevor ich neu installieren konnte.
Hab bald Urlaub, dann mache ich die Kiste platt und setze Windows neu auf ...
Steffen
[/OT]