1

I'm trying to kill a service process, if it stucks when trying to stop it via ServiceController. I have a Process object of this service; however, nothing happens when I call the Kill() method on it. No exceptions, and the process is still running.
So, how can I kill this process?

user626528
  • 13,999
  • 30
  • 78
  • 146
  • 1
    I think you'll need to supply some code. There's obviously more going on here than what you've described. – Mick Jan 14 '15 at 05:31
  • @Mick, nope. Nothing more is going on. PS every time I ask anything not-so-easy to answer, I have to spend lots of time proving that I'm not an idiot. Good job, SO. – user626528 Jan 14 '15 at 05:35
  • Well it's not a matter of you being an idiot, you've supplied us with an interpretation of what you think is happening, there's a good chance it's a misinterpretation, hence the reason why you've been unable to solve it. – Mick Jan 14 '15 at 05:38
  • 3
    This is probably related: [really-killing-a-process-in-windows](http://stackoverflow.com/questions/49988/really-killing-a-process-in-windows?rq=1) – thepirat000 Jan 14 '15 at 05:40
  • @Mick, you impugned my competence on a ground of blind guess. You could check if Kill() works on service processes instead, it takes just 1 minute. But you didn't. – user626528 Jan 14 '15 at 05:43
  • @thepirat000, yes. As far as I remember, service processes require some extra privileges to kill them. But I don't remember full details, unfortunately. – user626528 Jan 14 '15 at 05:46
  • What service is this? Do you have the ability to modify it, or is it some misbehaving third-party program? – Nathan Tuggy Jan 14 '15 at 07:14
  • @Nathan Tuggy, it's a third-party program. – user626528 Jan 14 '15 at 07:17
  • If the .NET function doesn't work, P/Invoke to TerminateProcess. – Harry Johnston Jan 15 '15 at 03:14
  • @Harry Johnston, this won't change anything. – user626528 Jan 15 '15 at 04:47
  • In case you're wondering I didn't rate your question down. Someone else thought it worthy of a down vote. You supply no source code then get haughty when asked for it, and you wonder why your questions don't get answered. – Mick Jan 15 '15 at 05:44
  • 1
    If TerminateProcess() doesn't work either, the most likely problem is that you forgot to enable debug privilege and/or didn't request the PROCESS_TERMINATE access right in the call to OpenProcess(). Either way the error code from TerminateProcess() would be 5, access denied. (If the error code is something else, it's a different problem. But we've got no hope of identifying it without at least knowing what the error code is.) – Harry Johnston Jan 15 '15 at 06:03
  • I can confirm that if those requirements are met, TerminateProcess() can kill a service process (tested on the WSearch service). – Harry Johnston Jan 15 '15 at 06:04
  • @Harry Johnston, now I remember, the "debug privilege" is what's necessary to do this. Why don't make this an answer? – user626528 Jan 15 '15 at 10:41

1 Answers1

2

There's nothing unusual about service processes from the kernel's point of view, but the permissions on them do not explicitly give PROCESS_TERMINATE access to the Administrators group. To bypass this, you need to enable debug privilege.

For reference, here's the code I used to confirm that nothing unexpected was happening:

#include <Windows.h>

#include <stdio.h>

int main(int argc, char ** argv)
{
    HANDLE h, hToken;
    DWORD pid = atoi(argv[1]);

    printf("Process %u\n", pid);

    if (OpenProcessToken(GetCurrentProcess(), 
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
    {
        struct {

            DWORD PrivilegeCount;
            LUID_AND_ATTRIBUTES Privileges[1];

        } tkp;

        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid); 

        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

        AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&tkp, 0, 
                (PTOKEN_PRIVILEGES)NULL, 0);

        CloseHandle(hToken);

    }

    h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (h == NULL)
    {
        printf("OpenProcess: %u\n", GetLastError());
        return 1;
    }

    if (!TerminateProcess(h, 1))
    {
        printf("TerminateProcess: %u\n", GetLastError());
        return 1;
    }

    printf("Done!\n");
    return 0;
}

I'm not sure how much of that can be done natively in C#, but you can P/Invoke the relevant calls if necessary.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158