Process termination, OpenNETCF

T

Tod Johnson

Hello,

I'm trying to implement the watchdog for my application, I mean the
process that will be watching for my application and detecting its
hanging. The question is how can I could terminate my application from
the watchdog if it detected that the program is locked?

At this moment I'm using:

....
Process t = Process.GetProcessById(Convert.ToInt32(_argv[0]));
t.WaitForExit(5000);
t.Kill();
Thread.Sleep(...);

but as I see it doesn't work :(

Thank you in advance,
Tod
 
P

Peter Foot [MVP]

In the current release build there is an error in the code used to Kill a
Process, if you already have the ProcessID then you can kill it with a
couple of P/Invokes
First call OpenProcess with the ProcessID to get a handle to the process
Then call TerminateProcess with this handle to kill the process
Finally call CloseHandle to close the handle to the process

The bug in the Kill method has been resolved in the online source, so you
could download the code and compile it within your project, in which case
the Kill method should work correctly.
http://www.opennetcf.org/sourcebrow...wroot/Source/OpenNETCF/Diagnostics/Process.cs

Peter
 
T

Tod Johnson

Peter,

thank you for your answer. It seems that the function
OpenNETCF.Diagnostics.Process.GetCurrentProcessID()

returns invalid the process id because when I try to open this process
inside another application through:

IntPtr pr = OpenProcess(0, false, (IntPtr)pid);
if (pr == IntPtr.Zero) throw new OpenNETCF.Win32.WinAPIException("Can't
open");

it returns an exception with the code 87 (Invalid parameter)! :(
Peter, are any thoughts?

Thank you
 
T

Tod Johnson

I've checked this two applications on the real device (ARMV4), the
problem is the same. it seems that ProcessID is incorrect :(
I'll drop here code snippets, maybe it'll help:

App1:
---------------------
using(StreamWriter sw = new StreamWriter("test.txt"))
{
sw.Write(OpenNETCFEx.Diagnostics.Process.GetCurrentProcessID());
}


App2:
--------------------
int pid;
using(StreamReader sr = new StreamReader("test.txt"))
{
pid = Convert.ToInt32(sr.ReadToEnd());
}


IntPtr pr = OpenProcess(0, false, (IntPtr)pid);
if (pr == IntPtr.Zero) throw new OpenNETCF.Win32.WinAPIException("Can't
open");
if (TerminateProcess(pr, 0))
{
if (CloseHandle(pr) == 0) {}
}
else
System.Windows.Forms.MessageBox.Show("Error!");


....

[DllImport("coredll", EntryPoint="OpenProcess", SetLastError=true)]
internal extern static IntPtr OpenProcess(uint fdwAccess, bool
fInherit, IntPtr IDProcess);

[DllImport("coredll.dll", EntryPoint="CloseHandle", SetLastError=true)]
internal static extern int CloseHandle(IntPtr hObject);

[DllImport("coredll.dll", EntryPoint="TerminateProcess",
SetLastError=true)]
internal extern static bool TerminateProcess(IntPtr hProcess, int
uExitCode);


Thank you!
 
T

Tod Johnson

Hello Peter,

I've found the problem:

public static int GetCurrentProcessID()
{
IntPtr pBase = new IntPtr((int) (GetPUserKData() + SYSHANDLE_OFFSET));
return Marshal.ReadInt32(pBase, SH_CURTHREAD * 4);
}

The offset for the ProcessID is SH_CURPROC, not SH_CURTHREAD.

Thanks anyway,
Tod
 
P

Peter Foot [MVP]

Thanks, there is a direct API call GetCurrentProcessId which is probably a
safer way to retrieve the id. I'll make sure this is fixed for v.Next.

Peter
 
G

Guest

Actually there isn't. GetCurrentProcessID is actually a Macro (like
SetEvent, PulseEvent). The call that he posted (when coirrfected for the
constant) is the only way to do it.

-Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top