I am writing a C# application that, among other things, automatically closes the advertisement a certain game displays after the user exits the game. My program accomplishes this by killing the game process when it detects that the user has exited the game. My program is similar to an Autohotkey script written by someone else that does similar things but it adds some features and a GUI.
Naturally, I used the Process.Kill method. However, that would fail with an "Access is denied" exception. I noticed that the Autohotkey script uses an unusual method of killing the process. I asked the author about it, and he said that he too had trouble killing the process with normal methods.
We suspect the reason normal process termination methods do not work is the HackShield software the game uses to attempt to combat cheating.
Here is the Autohotkey code the other guy's script uses for killing a process:
; kills all process instances of a given executable name
; COM AutoHotkey library code omitted
KillProcessInstances(exe)
{
psvc := COM_GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
pset := COM_Invoke(psvc, "ExecQuery", "Select * from Win32_Process Where Name = '" exe "'")
penm := COM_Invoke(pset, "_NewEnum")
Loop, % COM_Invoke(pset, "Count")
If COM_Enumerate(penm, pobj)=0
{
COM_Invoke(pobj, "Terminate")
COM_Release(pobj)
}
COM_Release(penm)
COM_Release(pset)
COM_Release(psvc)
}
I replaced the Process.KIll with the WMI calls in my program using the System.Management namespace and my program is now able to kill the process.
What I don't understand is what makes the WMI any different from Process.Kill. I would expect both to work or both to fail. In addition, Task Manager is able to kill the process just fine, but I would think it just uses a TerminateProcess win32 call just as Process.Kill surely does. Can anyone shed some light on the cause of the different behavior? If it matters, I'm running Windows XP.
Edit: wj32 explained why the WMI works, but can anyone explain why I can kill the process with Task Manager but not with my own program?
WMI calls are not performed within the security context of your process. They are handled in another process (I'm guessing the Winmgmt service). This service runs under the SYSTEM account, and HackShield may be allowing the termination continue due to this.
Related
Related to a question I asked here -- I have a process that I launched which is in a "suspended" state. I cannot kill or resume this process through any of the normal means (process explorer, task manager, WinDbg).
Logging-out of my session DOES kill this process though. How? What mechanism is the OS using when I log out that is somehow different to what Process Explorer is trying to do?
Edit: To clarify - I am assuming that Process Explorer is calling the TerminateProcess API function when it tries to kill a process. Something in the process state is stopping this from working though. Logging out obviously invokes some different behaviour and Windows ignores whatever was blocking TerminateProcess, and kills the process due to my session ending.
As a user, is there any different way to try and terminate a process other than calling the TerminateProcess API?
Process Explorer can't kill a process itself; it can only ask the OS to do so. The OS itself doesn't have to play by its own rules.
Remember, it's the OS itself which defines what a process is. It might very well define a process as part of a logon session. This would imply that if you clean up the whole session then you don't need to clean up individual processes. Just like you don't need to bother with CloseHandle before ExitProcess either.
I have an application made with matlab compiler.
I want to do some shutdown activities whenever it ends. As it seems to be impossible to catch signals in matlab (or I'm not able to), I checked to use onCleanup (Matlab: Is it possible to create signal handlers (.m scripts)). It is working within matlab (native), but not within the compiled application.
I tried to end the application with CTRL-C and with taskkill (which only work with /f). In both cases the onCleanup-method was NOT executed.
For testing purposes here
function sigtest(varargin)
remainder=onCleanup(#()save('exit.mat'));
b=1;
while true
disp(datestr(now));
a=rand(round(5*b));%to be saved
pause(10);
b=a(1);
end
my source code, which I compiled via mcc -m -v sigtest.m.
As onether try, I inserted the lines
myexiter=addlistener(System.AppDomain.CurrentDomain,'ProcessExit',...
#(a,b)save('listexit.mat'));
after line 2, but also this .NET-Event is not working.
If you're registering shutdown activities within M-code, they're only going to work on a graceful shutdown of the process. The taskkill /f command will do a "forceful" shutdown, which I think will terminate the process immediately. The Matlab interpreter won't get a chance to run whatever cleanup code is still pending. I think Ctrl-C on a console application (which the compiled sigtest.m will be running as) will have the same effect. Same applies to the .NET-Event: if you forcefully kill the process, that callback never gets a chance to run.
If you want on-exit code, or any other cleanup stuff, to run, you need to find a way for the program to find out when it should exit and initiate a more graceful shutdown itself. For example, in your sigtest example, you could check stdin at the end of every pass through the loop, see if the user has typed 'quit', and if so call exit(). Then your onCleanup stuff should run.
In a GUI compiled Matlab application, this is more straightforward; you have GUI controls to exit the application. I don't know what the canonical way is to make a console compiled Matlab application responsive to user exit requests, or if there even is a good one. You might want to make this a GUI app if you think the user might want to request a graceful abort of its operation.
Heres a simple question - is there anyway that a non-console (ie a CWinApp) application can receive and process CTRL+BREAK, it would appear SetConsoleCtrlHandler doesnt do the job nor the installation of signal handlers?
I unfortunately am working with a legacy CDialog based app which is run under the control of Microsoft HPC and HPC uses CTRL+BREAK to cancel the program (assuming i guess that nobody in their right mind would have a non-console app running in the background)
Cheers.
Calling AttachConsole with ATTACH_PARENT_PROCESS should do the trick. This will attach your process to the HPC console so that it can receive the control-break signal. You should probably do this before calling SetConsoleCtrlHandler.
If that doesn't work, try AllocConsole instead. If HPC doesn't have a console of its own, it might be assuming that the sub-process will have created a new console group (this happens automatically for console-mode applications) in which case it will be sending a control-break signal to the sub-process PID. If so, it shouldn't matter whether the console group was created automatically or explicitly.
You may wish to start by making sure that HPC is indeed sending a control-break signal (presumably via GenerateConsoleCtrlEvent) by checking that SetConsoleCtrlHandler works as expected for a console-mode application. If it is calling TerminateProcess instead then there is nothing you can do about it.
We've got issues with our program potentially hanging in certain situations, is there a way to search and destroy your own program with windows calls without using task manager. It probably wouldn't make sense to include this in the program itself, but as a bundled thing no one would see.
What's the best way to go about doing this, how deep do I need to dig to stop my program and how shallow should I keep to make sure I don't crash the OS?
You could create a .bat file and put a Taskkill command in it to forcefully terminate your application. The command would look something like this:
taskkill /f /im notepad.exe
Although you should probably fix the situation in which it hangs, one way you could have the program kill itself is to spawn a new thread when you launch the app, and have that thread poll the application and kill it if necessary.
Killing a thread in windows.
One option would be to write a Windows Service that serves as a Watchdog. You could find your program by it's .exename and then you need some way to determine if it hangs (for example some simple Inter-Process-Communication or even a Client/Server thing) and restart it if necessary.
That is hardly "no one would see" though.
You can terminate a process using TerminateProcess. You'll need to determine the target process id using EnumProcesses and then call OpenProcess to obtain a handle to the process in order to terminate it.
You can enumerate running processes using the EnumProcesses() function. This will let you search for the process name, and get the PID. With the PID, you can open a HANDLE to the process which you need in order to call TerminateProcess() to kill the hung process.
There's an example of how to use EnumProcesses on MSDN.
Some pseudo-code might look something like:
EnumProcesses(pidArray, sizeofArray, &bytesReturned);
for(int i=0; i < bytesReturned/sizeof(DWORD); i++) {
if(getProcessName(pidArray[i]) == "ourProcess"){
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pidArray[i]);
TerminateProcess(hProc, 0);
}
}
What about implementing something from the pstools of sysinternals ?
I am looking for different ways to pause and resume programmatically a particular process via its process ID under Windows XP.
Process suspend/resume tool does it with SuspendThread / ResumeThread but warns about multi-threaded programs and deadlock problems.
PsSuspend looks okay, but I wonder if it does anything special about deadlocks or uses another method?
Prefered languages : C++ / Python
If you "debug the debugger" (for instance, using logger.exe to trace all API calls made by windbg.exe), it appears that the debugger uses SuspendThread()/ResumeThread() to suspend all of the threads in the process being debugged.
PsSuspend may use a different way of suspending processes (I'm not sure), but it is still possible to hang other processes: if the process you're suspending is holding a shared synchronization object that is needed by another process, you may block that other process from making any progress. If both programs are well-written, they should recover when you resume the one that you suspended, but not all programs are well-written. And if this causes your program that is doing the suspending to hang, then you have a deadlock.
I'm not sure if this does the job, but with ProcessExplorer from MS Systernals you can suspend a process.
It's been said here: https://superuser.com/a/155263 and I found it there too.
read here and you also have psutil for python that you can use it like that:
>>> import psutil
>>> pid = 7012
>>> p = psutil.Process(pid)
>>> p.suspend()
>>> p.resume()
I tested http://www.codeproject.com/KB/threads/pausep.aspx on few softwares:
it works fine.
PsSuspend and Pausep are two valid options.
So, after I found about UniversalPauseButton, Googling for this ("windows SIGSTOP"), getting this question as the first search result (thanks Ilia K. your comment did its job), and reading the answers, I went back to checkout the code.
Apparently, it uses undocumented NT kernel and Win32 APIs _NtSuspendProcess, _NtResumeProcess and _HungWindowFromGhostWindow.
PsSuspend, the utility you mentioned and linked to probably uses these APIs, I couldn't verify this, the source code isn't supplied, only executables and a EULA, you can probably figure that out by disassembling the binary but it's against the EULA.
so, to answer your specific question, checkout UniversalPauseButton's main.cpp, basically you call _NtSuspendProcess(ProcessHandle) and _NtResumeProcess(ProcessHandle), ProcessHandle being the handle of the process you want to pause or resume.
I think there is a good reason why there is no SuspendProcess() function in Windows. Having such a function opens the door for an unstable system. You shall not suspend a process unless you created that process yourself.
If you wrote that process yourself, you could use an event (see ::SetEvent() etc. in MSDN) or another kind of messaging to trigger a pause command in the process.