Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Need function to Kill a program

1 view
Skip to first unread message

Dos-Man

unread,
Sep 27, 2003, 10:03:39 PM9/27/03
to
Platform: Windows 98
Language: Visual C++ 6 (non-mfc application)

Hi,

I need a function that accepts a window handle as its argument
and kills that application dead; no chance for the application
to do anything, no worries about what it is doing, etc. I'm
not very knowledgable about things like processes and threads.

This is specifically designed for my own personal "End Task" replacement
on my 98 machine, so it doesn't have to work on other versions of Windows.

Can anyone help me out?

dos-man

Phlip

unread,
Sep 27, 2003, 10:36:48 PM9/27/03
to
> I need a function that accepts a window handle as its argument
> and kills that application dead; no chance for the application
> to do anything, no worries about what it is doing, etc. I'm
> not very knowledgable about things like processes and threads.

If you would accept a program that takes the command line name of the
program as a command line argument, save the source below my sig to a file
called killall.cpp, open this file in MSDEV, and tap F7. MSDEV will build a
default DSP file for it and compile it.

Warning: This program kills everything starting with the string supplied, at
a minimum of 4 letters.


Phlip

unread,
Sep 27, 2003, 10:40:01 PM9/27/03
to
> I need a function that accepts a window handle as its argument
> and kills that application dead; no chance for the application
> to do anything, no worries about what it is doing, etc. I'm
> not very knowledgable about things like processes and threads.

If you would accept a program that takes the command line name of the
program as a command line argument, save the source below my sig to a file
called killall.cpp, open this file in MSDEV, and tap F7. MSDEV will build a
default DSP file for it and compile it.

It uses PSAPI.LIB from the Platform SDK.

Warning: This program kills everything starting with the string supplied, at

a minimum of 4 letters. And it takes multiple command line args.

--
Phlip

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows
headers

#include <windows.h>
#include <stdio.h>
#include "C:/Program Files/Microsoft SDK/include/Psapi.h"
#pragma comment(lib, "C:/Program Files/Microsoft SDK/Lib/Psapi.Lib")

void
PrintProcessName(DWORD processID, char const * processName)
{
char szProcessName[MAX_PATH] = "unknown";

// Get a handle to the passed-in process ID
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );

// Get the process name
if(hProcess)
{
HMODULE hMod;
DWORD cbNeeded;

if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
GetModuleBaseName(hProcess, hMod, szProcessName,
sizeof(szProcessName));
}
}

// printf("%s (PID: %u)\n", szProcessName, processID );

if( 0 == strnicmp(szProcessName, processName, strlen(processName)))
{
printf ("%s (PID to terminate: %u)\n", szProcessName, processID);
HANDLE g_hProcess (OpenProcess(PROCESS_ALL_ACCESS, FALSE,
processID ));

if (g_hProcess)
{
DWORD dwExitCode(0);

if ( GetExitCodeProcess (g_hProcess, &dwExitCode) != 0)
{
printf ("Exit code for %s: %u\n", processName, dwExitCode);
TerminateProcess (g_hProcess, dwExitCode);
printf ("Process: %u, was sucessfully terminated.\n", dwExitCode);
}
else
printf ("Could not get ExitCode.\n");
}
}

CloseHandle(hProcess);

}


int
killProcess(char const * processName)
{

DWORD aProcesses[1024], // Array of process IDs
cbNeeded, // Byte count returned...
cProcesses; // The number of 'em obtained
DWORD dwExitCode = STILL_ACTIVE;
unsigned int i;


// Get a list of all current PIDs running
if(!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
return 0;

// Get the count of PIDs in the array
cProcesses = cbNeeded / sizeof(DWORD);

// Print the name and process identifier for each process
for(i = 0; i < cProcesses; i++)
PrintProcessName(aProcesses[i], processName);

/* g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_processID );

if (g_hProcess)
{
if ( GetExitCodeProcess (g_hProcess, &dwExitCode) != 0)
{
fprintf (fp, "Exit code for ntdvm.exe: %u\n", dwExitCode);
TerminateProcess (g_hProcess, dwExitCode);
fprintf (fp, "Process: %u, was sucessfully terminated.\n", dwExitCode);
}
else
fprintf (fp, "Could not get ExitCode.\n");
}
*/
return 0;
}


int
main(int argc, char* argv[])
{
char static const syntax[] = "syntax: killall <process name>...";

// TODO without a process name, we should work like ps

if (argc < 2)
puts (syntax);
else
for (int idx (1); idx < argc; ++idx)
{
char const * processName = argv[idx];

if (processName == NULL || strlen(processName) < 4)
puts (syntax);
else
killProcess(processName);
}
return 0;
}

Dos-Man

unread,
Sep 28, 2003, 8:49:50 PM9/28/03
to
"Phlip" <phli...@yahoo.com> wrote in message news:<5Srdb.2725$TJ5...@newssvr16.news.prodigy.com>...

I greatly appreciate your taking the time to post.
Not quite what I am looking for, though.

What I really need to do is figure out how to
obtain a process handle given the window's caption text
(if any), and it's class name.

Once I have this process handle, I think I can write the
necessary code to terminate it. I'll just keep using
WM_CLOSE until I can figure it out.

dos-man

Phlip

unread,
Sep 28, 2003, 9:34:52 PM9/28/03
to
> Not quite what I am looking for, though.
>
> What I really need to do is figure out how to
> obtain a process handle given the window's caption text
> (if any), and it's class name.

PSAPI.DLL, the library I introduced, supports the Task Manager.

This supports an Applications list (the top-level window names), and can "Go
To Process" for each one.

Investigate PSAPI.H, and Google for sample code showing its other functions.
Your result will come out very similar to my program.

--
Phlip


goose

unread,
Sep 29, 2003, 6:37:33 AM9/29/03
to
Chai...@mail.com (Dos-Man) wrote in message news:<e4bc58ab.03092...@posting.google.com>...

wrote this some time back, it was /intended/ gpl, but now
that i've posted it here, it'll be in the public
domain :-).

goose,

/* public domain code */
#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <winbase.h>
#include <tlhelp32.h>

/* TODO: user must be able to specify the order that
they want the columns listed ...
*/
#define HELP_STRING\
"usage:\nwps.exe [flags]\n "\
"where flags are any of the following in any order\n"\
"a - print all available columns\n"\
"u - number of processes using this process\n"\
"p - process ID\n"\
"h - heap ID\n"\
"m - module ID\n"\
"t - number of threads\n"\
"P - parent process ID\n"\
"f - flags of the process\n"\
"b - base class of process\n"\
"n - process name\n"\
/*
"\n\nthe order specified is the order that the columns"\
" printed in\n\n"
this bit is for version 1.1 only */

#define VERSION_STRING "wps version 1.0\n"

struct columns_t {
short int usage;
short int pid;
short int hid;
short int mid;
short int threads;
short int ppid;
short int flags;
short int pcb;
short int name;
};

struct columns_t get_columns (int argc, char **argv) {
struct columns_t retvalue;
memset (&retvalue, 0, sizeof retvalue);
while (--argc) {
size_t i = strlen (argv[argc]);
while (i--) {
switch (argv[argc][i]) {
case 'a':
memset (&retvalue, 0xff, sizeof retvalue);
break;
case 'u':
retvalue.usage = 1;
break;
case 'p':
retvalue.pid = 1;
break;
case 'h':
retvalue.hid = 1;
break;
case 'm':
retvalue.mid = 1;
break;
case 't':
retvalue.threads = 1;
break;
case 'P':
retvalue.ppid = 1;
break;
case 'f':
retvalue.flags = 1;
break;
case 'b':
retvalue.pcb = 1;
break;
case 'n':
retvalue.name = 1;
break;
}
}
}
return retvalue;
}

void print_process_headers (struct columns_t *cols) {
if (cols->usage) {
printf ("usage\t");
}
if (cols->pid) {
printf ("ProcessID\t");
}
if (cols->hid) {
printf ("HeapID \t");
}
if (cols->mid) {
printf ("ModuleID\t");
}
if (cols->threads) {
printf ("threads\t");
}
if (cols->ppid) {
printf ("ParentID\t");
}
if (cols->flags) {
printf ("flags\t");
}
if (cols->pcb) {
printf ("PCB\t");
}
if (cols->name) {
printf ("name\t");
}
printf ("\n");
}

void print_process (PROCESSENTRY32 *p, struct columns_t *cols) {

if (cols->usage) {
printf ("%04u\t", p->cntUsage);
}
if (cols->pid) {
printf ("%010u\t", p->th32ProcessID);
}
if (cols->hid) {
printf ("%010u\t", p->th32DefaultHeapID);
}
if (cols->mid) {
printf ("%010u\t", p->th32ModuleID);
}
if (cols->threads) {
printf ("%04u\t", p->cntThreads);
}
if (cols->ppid) {
printf ("%010u\t", p->th32ParentProcessID);
}
if (cols->flags) {
printf ("%04u\t", p->dwFlags);
}
if (cols->pcb) {
printf ("%04u\t", p->pcPriClassBase);
}
if (cols->name) {
printf ("%s\t", p->szExeFile);
}
printf ("\n");
}

int main (int argc, char **argv) {
HANDLE all_procs;
PROCESSENTRY32 curr_proc = {0};
struct columns_t columns;

if (argc<2) {
printf ("%s\n%s\n", VERSION_STRING, HELP_STRING);
return EXIT_SUCCESS;
}
if (argv[0]==NULL) {
return 0;
}

columns = get_columns (argc, argv);
print_process_headers (&columns);
all_procs = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
if (all_procs==-1) {
printf ("never got the snapshot, ending now\n");
return EXIT_FAILURE;
}
curr_proc.dwSize = sizeof curr_proc;

if (Process32First (all_procs, &curr_proc)==FALSE) {
printf ("no processes found ?\n");
CloseHandle (all_procs);
return 42;
} else {
print_process (&curr_proc, &columns);
}

while (Process32Next (all_procs, &curr_proc)==TRUE) {
print_process (&curr_proc, &columns);
}
printf ("\n");
CloseHandle (all_procs);
return EXIT_SUCCESS;
}

Dos-Man

unread,
Sep 29, 2003, 9:29:51 AM9/29/03
to
"Phlip" <phli...@yahoo.com> wrote in message news:<0%Ldb.3439$3T1...@newssvr16.news.prodigy.com>...

I accomplished the task at hand. It seems
prone to crash the computer but... I will only be using this
app when the computer is already crashed or crashing :)
It seems to work fine on "simple" applications, but when
I closed an explorer window chaos broke out.

I have been fighting with Visual C++ for days, and spent an
unbelievable amount of time compiling, recompiling, and searching
all available programming docs. When it finally worked, I
couldn't believe it.

At any rate, here is how I did it:

First, I created a function that takes a window as it's arg
and returns a process ID.

----------------------------------------------------------
DWORD ProcIDFromWnd(HWND a)
{
DWORD idProc;
GetWindowThreadProcessId(a, &idProc);
return(idProc);
}
----------------------------------------------------------

I then called this function to obtain the process ID, called
OpenProcess with PROCESS_ALL_ACCESS priviledge to the thread,
and terminated the process.

HANDLE hProcess;
DWORD ProcId;
BOOL TermSucc;

ProcId = (DWORD)ProcIDFromWnd(globalHandle);

hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcId);

if (hProcess == NULL)
MessageBox(hwnd, "Invalid process handle was returned.
Terminating... ", "End Task", MB_OK |
MB_ICONEXCLAMATION);

TermSucc = TerminateProcess(hProcess, 0);

if (TermSucc == FALSE)
MessageBox(hwnd, "The application could not be shut
down.", "End Task", MB_OK | MB_ICONEXCLAMATION);

Willem

unread,
Sep 29, 2003, 9:48:27 AM9/29/03
to
Dos-Man wrote:
) I accomplished the task at hand. It seems
) prone to crash the computer but... I will only be using this
) app when the computer is already crashed or crashing :)

) It seems to work fine on "simple" applications, but when
) I closed an explorer window chaos broke out.

Duh. All explorer windows are managed by the same task, which also happens
to manage the whole desktop interface.
So if you 'kill' an 'explorer window', your whole desktop goes boom.


SaSW, Willem (at stack dot nl)
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Dos-Man

unread,
Sep 30, 2003, 9:25:16 AM9/30/03
to
Willem <wil...@stack.nl> wrote in message news:<slrnbnge1b...@toad.stack.nl>...

> Dos-Man wrote:
> ) I accomplished the task at hand. It seems
> ) prone to crash the computer but... I will only be using this
> ) app when the computer is already crashed or crashing :)
> ) It seems to work fine on "simple" applications, but when
> ) I closed an explorer window chaos broke out.
>
> Duh. All explorer windows are managed by the same task, which also happens
> to manage the whole desktop interface.
> So if you 'kill' an 'explorer window', your whole desktop goes boom.
>
>
> SaSW, Willem (at stack dot nl)

Now you tell me :)

dos-man

0 new messages