Skip to content

対象プロセスを一時停止するホットキー機能を追加する #558

@Freeesia

Description

@Freeesia

Alt

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;

public static class ProcessSuspendResume
{
    // Win8+ あたりから使える権限(古い環境向けに AllAccess を使う手もあるが推奨しない)
    private const int PROCESS_SUSPEND_RESUME = 0x0800;
    private const int PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr OpenProcess(int desiredAccess, bool inheritHandle, int processId);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    [DllImport("ntdll.dll")]
    private static extern int NtSuspendProcess(IntPtr processHandle);

    [DllImport("ntdll.dll")]
    private static extern int NtResumeProcess(IntPtr processHandle);

    public static void Suspend(int pid)
    {
        var h = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_QUERY_LIMITED_INFORMATION, false, pid);
        if (h == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcess failed");

        try
        {
            int status = NtSuspendProcess(h);
            if (status != 0) throw new InvalidOperationException($"NtSuspendProcess failed. NTSTATUS=0x{status:X8}");
        }
        finally
        {
            CloseHandle(h);
        }
    }

    public static void Resume(int pid)
    {
        var h = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_QUERY_LIMITED_INFORMATION, false, pid);
        if (h == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcess failed");

        try
        {
            int status = NtResumeProcess(h);
            if (status != 0) throw new InvalidOperationException($"NtResumeProcess failed. NTSTATUS=0x{status:X8}");
        }
        finally
        {
            CloseHandle(h);
        }
    }

    public static int GetPidByNameSingle(string processName)
    {
        var ps = Process.GetProcessesByName(processName);
        if (ps.Length == 0) throw new InvalidOperationException("Process not found.");
        if (ps.Length > 1) throw new InvalidOperationException("Multiple processes found. Use PID.");
        return ps[0].Id;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions