Unter Unix können wir eine Prozessausführung vorübergehend unterbrechen und mit Signalen SIGSTOP
und fortsetzen SIGCONT
. Wie kann ich einen Single-Thread-Prozess in Windows ohne Programmierung anhalten?
Unter Unix können wir eine Prozessausführung vorübergehend unterbrechen und mit Signalen SIGSTOP
und fortsetzen SIGCONT
. Wie kann ich einen Single-Thread-Prozess in Windows ohne Programmierung anhalten?
Antworten:
Sie können es nicht über die Befehlszeile tun, Sie müssen Code schreiben (ich nehme an, Sie suchen nicht nur nach einem Dienstprogramm, sonst ist Super User möglicherweise ein besserer Ort, um zu fragen). Ich gehe auch davon aus, dass Ihre Anwendung über alle erforderlichen Berechtigungen verfügt (Beispiele sind ohne Fehlerprüfung).
Holen Sie sich zuerst alle Threads eines bestimmten Prozesses und rufen Sie dann die SuspendThread
Funktion auf, um jeden einzelnen zu stoppen (und ResumeThread
fortzusetzen). Es funktioniert, aber einige Anwendungen können abstürzen oder hängen bleiben, weil ein Thread an einem beliebigen Punkt gestoppt werden kann und die Reihenfolge des Anhaltens / Fortsetzens nicht vorhersehbar ist (dies kann beispielsweise zu einer Deadlock führen). Für eine Single-Threaded-Anwendung ist dies möglicherweise kein Problem.
void suspend(DWORD processId)
{
HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 threadEntry;
threadEntry.dwSize = sizeof(THREADENTRY32);
Thread32First(hThreadSnapshot, &threadEntry);
do
{
if (threadEntry.th32OwnerProcessID == processId)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE,
threadEntry.th32ThreadID);
SuspendThread(hThread);
CloseHandle(hThread);
}
} while (Thread32Next(hThreadSnapshot, &threadEntry));
CloseHandle(hThreadSnapshot);
}
Bitte beachten Sie, dass diese Funktion sogar zu naiv ist. Um Threads fortzusetzen, sollten Sie gesperrte Threads überspringen. Aufgrund der Reihenfolge des Suspendierens / Fortsetzens kann es leicht zu einem Deadlock kommen. Für Single-Threaded-Anwendungen ist es Prolix, aber es funktioniert.
Ab Windows XP gibt es das, NtSuspendProcess
aber es ist nicht dokumentiert . In diesem Beitrag finden Sie ein Codebeispiel (Referenz für undokumentierte Funktionen: news: //comp.os.ms-windows.programmer.win32).
typedef LONG (NTAPI *NtSuspendProcess)(IN HANDLE ProcessHandle);
void suspend(DWORD processId)
{
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId));
NtSuspendProcess pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(
GetModuleHandle("ntdll"), "NtSuspendProcess");
pfnNtSuspendProcess(processHandle);
CloseHandle(processHandle);
}
Ein Programm anzuhalten ist das, was normalerweise ein Debugger tut. Dazu können Sie die DebugActiveProcess
Funktion verwenden. Die Prozessausführung wird angehalten (mit allen Threads zusammen). Zum Fortsetzen können Sie verwenden DebugActiveProcessStop
.
Mit dieser Funktion können Sie einen Prozess stoppen (anhand seiner Prozess-ID). Die Syntax ist sehr einfach: Übergeben Sie einfach die ID des Prozesses, den Sie et-voila stoppen möchten. Wenn Sie eine Befehlszeilenanwendung erstellen, müssen Sie deren Instanz weiter ausführen, damit der Prozess angehalten bleibt (oder er wird beendet). Weitere Informationen finden Sie im Abschnitt " Anmerkungen " zu MSDN.
void suspend(DWORD processId)
{
DebugActiveProcess(processId);
}
Wie gesagt, die Windows-Befehlszeile verfügt über kein Dienstprogramm, aber Sie können eine Windows-API-Funktion über PowerShell aufrufen. Installieren Sie zuerst das Invoke-WindowsApi- Skript, dann können Sie Folgendes schreiben:
Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)
Natürlich, wenn Sie es oft brauchen, können Sie eine alias
dafür machen .
Invoke-WindowsApi
) , die Sie lassen invoke eine Windows - API ( PASCAL
Aufrufkonvention, allgemein WINAPI
) C - Funktion. Es ist nicht Teil von PowerShell, dann muss es separat heruntergeladen und installiert werden .
Ohne ein externes Tool können Sie dies einfach unter Windows 7 oder 8 erreichen, indem Sie den Ressourcenmonitor und auf der Registerkarte CPU oder Übersicht mit der rechten Maustaste auf den Prozess klicken und Prozess anhalten auswählen . Der Ressourcenmonitor kann auf der Registerkarte Leistung des Task-Managers gestartet werden.
procexp.exe
!
Ich verwende (einen sehr alten) Prozess-Explorer von SysInternals (procexp.exe). Es ist ein Ersatz / eine Ergänzung zum Standard-Task-Manager. Von dort aus können Sie einen Prozess anhalten.
Bearbeiten: Microsoft hat über SysInternals gekauft, URL: procExp.exe
Ansonsten können Sie die Prozesspriorität auf niedrig setzen, damit sie anderen Prozessen nicht im Wege steht. Dadurch wird der Prozess jedoch nicht angehalten.
PsSuspend- Befehlszeilenprogramm aus der SysInternals
Suite. Es unterbricht / setzt einen Prozess anhand seiner ID fort.
Nun, Process Explorer hat eine Suspend-Option. Sie können mit der rechten Maustaste auf einen Prozess in der Prozessspalte klicken und Suspend auswählen. Sobald Sie bereit sind, es wieder aufzunehmen, klicken Sie mit der rechten Maustaste und wählen Sie dieses Mal Fortsetzen. Der Prozess-Explorer ist hier erhältlich:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
PsSuspend unterbricht , wie von Vadzim erwähnt , sogar einen Prozess mit seinem Namen, nicht nur mit pid.
Ich verwende sowohl PsSuspend als auch PsList (ein weiteres Tool aus der PsTools-Suite) in einem einfachen Umschaltskript für den OneDrive-Prozess: Wenn ich mehr Bandbreite benötige, unterbreche ich die OneDrive-Synchronisierung und setze den Prozess anschließend fort, indem ich dasselbe Miniskript ausstelle:
PsList -d onedrive|find/i "suspend" && PsSuspend -r onedrive || PsSuspend onedrive
PsSuspend- Befehlszeilenprogramm aus der SysInternals
Suite. Es unterbricht / setzt einen Prozess anhand seiner ID fort.
#pragma comment(lib,"ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtSuspendProcess(IN HANDLE ProcessHandle);
void SuspendSelf(){
NtSuspendProcess(GetCurrentProcess());
}
ntdll enthält die exportierte Funktion NtSuspendProcess. Übergeben Sie das Handle an einen Prozess, um den Trick auszuführen.