<p>How do I suspend a whole process (like the Process Explorer does when I click Suspend) in C#.</p>

<p>I'm starting the Process with Process.Start, and on a certain event, I want to suspend the process to be able to do some investigation on a "snapshot" of it.</p>

[{'answer_id': 71290, 'author': 'Dave Moore', 'author_id': 6996, 'author_profile': 'https://Stackoverflow.com/users/6996', 'pm_score': 1, 'selected': False, 'text': '<p>See this CodeProject article for the win32 basics : <a href="http://www.codeproject.com/KB/threads/pausep.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/threads/pausep.aspx</a>.  This sample code makes use of the ToolHelp32 library from the SDK, so I would recommend turning this sample code into an unmanaged C++/CLI library with a simple interface like "SuspendProcess(uint processID).</p>\n\n<p>Process.Start will return you a Process object, from which you can get the process id, and then pass this to your new library based on the above.</p>\n\n<p>Dave</p>\n'}, {'answer_id': 71457, 'author': 'Magnus Johansson', 'author_id': 3584, 'author_profile': 'https://Stackoverflow.com/users/3584', 'pm_score': 6, 'selected': True, 'text': '<p>Here\'s my suggestion:</p>\n\n<pre><code> [Flags]\n    public enum ThreadAccess : int\n    {\n      TERMINATE = (0x0001),\n      SUSPEND_RESUME = (0x0002),\n      GET_CONTEXT = (0x0008),\n      SET_CONTEXT = (0x0010),\n      SET_INFORMATION = (0x0020),\n      QUERY_INFORMATION = (0x0040),\n      SET_THREAD_TOKEN = (0x0080),\n      IMPERSONATE = (0x0100),\n      DIRECT_IMPERSONATION = (0x0200)\n    }\n\n    [DllImport("kernel32.dll")]\n    static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);\n    [DllImport("kernel32.dll")]\n    static extern uint SuspendThread(IntPtr hThread);\n    [DllImport("kernel32.dll")]\n    static extern int ResumeThread(IntPtr hThread);\n    [DllImport("kernel32", CharSet = CharSet.Auto,SetLastError = true)]\n    static extern bool CloseHandle(IntPtr handle);\n\n\nprivate static void SuspendProcess(int pid)\n{\n  var process = Process.GetProcessById(pid); // throws exception if process does not exist\n\n  foreach (ProcessThread pT in process.Threads)\n  {\n    IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);\n\n    if (pOpenThread == IntPtr.Zero)\n    {\n      continue;\n    }\n\n    SuspendThread(pOpenThread);\n\n    CloseHandle(pOpenThread);\n  }\n}\n\npublic static void ResumeProcess(int pid)\n{\n  var process = Process.GetProcessById(pid);\n\n  if (process.ProcessName == string.Empty)\n    return;\n\n  foreach (ProcessThread pT in process.Threads)\n  {\n    IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);\n\n    if (pOpenThread == IntPtr.Zero)\n    {\n      continue;\n    }\n\n    var suspendCount = 0;\n    do\n    {\n      suspendCount = ResumeThread(pOpenThread);\n    } while (suspendCount &gt; 0);\n\n    CloseHandle(pOpenThread);\n  }\n}\n</code></pre>\n'}, {'answer_id': 1073037, 'author': 'RandomNickName42', 'author_id': 67819, 'author_profile': 'https://Stackoverflow.com/users/67819', 'pm_score': 2, 'selected': False, 'text': '<p>So really, what the other answer\'s are showing is suspending thread\'s in the process, there is no way to really suspend the process (i.e. in one call).... </p>\n\n<p>A bit of a different solution would be to actually debug the target process which you are starting, see <a href="http://blogs.msdn.com/jmstall/archive/2006/07/03/managed-Vs-native-apis.aspx" rel="nofollow noreferrer">Mike Stall\'s blog</a> for some advice how to implement this from a managed context. </p>\n\n<p>If you implement a debugger, you will be able to scan memory or what other snap-shotting you would like.</p>\n\n<p>However, I would like to point out, that technically, there is now way to really do this.  Even if you do debugbreak a target debuggee process, another process on your system may inject a thread and will be given some ability to execute code regardless of the state of the target process (even let\'s say if it\'s hit a breakpoint due to an access violation), if you have all thread\'s suspended up to a super high suspend count, are currently at a break point in the main process thread and any other such presumed-frozen status, it is still possible for the system to inject another thread into that process and execute some instructions.  You could also go through the trouble of modifying or replacing all of the entry point\'s the <a href="http://www.nynaeve.net/?p=205" rel="nofollow noreferrer">kernel usually calls</a> and so on, but you\'ve now entered the viscous arm\'s race of MALWARE ;)...</p>\n\n<p>In any case, using the managed interfaces for debugging seems\' a fair amount easier than p/invoke\'ng a lot of native API call\'s which will do a poor job of emulating what you probably really want to be doing... using debug api\'s ;)</p>\n'}, {'answer_id': 13109774, 'author': 'Sarath', 'author_id': 353241, 'author_profile': 'https://Stackoverflow.com/users/353241', 'pm_score': 4, 'selected': False, 'text': '<p>Thanks to Magnus</p>\n\n<p>After including the Flags, I modified the code a bit to be an extension method in my project. I could now use</p>\n\n<pre><code>var process = Process.GetProcessById(param.PId);\nprocess.Suspend();\n</code></pre>\n\n<p>Here is the code for those who might be interested.</p>\n\n<pre><code>public static class ProcessExtension\n{\n    [DllImport("kernel32.dll")]\n    static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);\n    [DllImport("kernel32.dll")]\n    static extern uint SuspendThread(IntPtr hThread);\n    [DllImport("kernel32.dll")]\n    static extern int ResumeThread(IntPtr hThread);\n\n    public static void Suspend(this Process process)\n    {\n        foreach (ProcessThread thread in process.Threads)\n        {\n            var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);\n            if (pOpenThread == IntPtr.Zero)\n            {\n                break;\n            }\n            SuspendThread(pOpenThread);\n        }\n    }\n    public static void Resume(this Process process)\n    {\n        foreach (ProcessThread thread in process.Threads)\n        {\n            var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);\n            if (pOpenThread == IntPtr.Zero)\n            {\n                break;\n            }\n            ResumeThread(pOpenThread);\n        }\n    }\n}\n</code></pre>\n\n<p>I have a utility done which I use to generally suspend/kill/list a process. Full source is <a href="https://github.com/SarathR/ProcessUtil.git" rel="noreferrer">on Git</a></p>\n'}, {'answer_id': 61282905, 'author': 'gerrard', 'author_id': 13148843, 'author_profile': 'https://Stackoverflow.com/users/13148843', 'pm_score': 1, 'selected': False, 'text': '<pre><code>[DllImport("ntdll.dll", PreserveSig = false)]\n    public static extern void NtSuspendProcess(IntPtr processHandle);\n    static IntPtr handle;\n\n        string p = "";\n        foreach (Process item in Process.GetProcesses())\n        {\n            if (item.ProcessName == "GammaVPN")\n            {\n                p = item.ProcessName;\n                handle = item.Handle;\n                NtSuspendProcess(handle);\n            }\n        }\n        Console.WriteLine(p);\n        Console.WriteLine("done");\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/71257', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/9632/']