Killing an Unmanaged VB6 COM Process from C#

  • Thread starter Christopher G. Carnahan
  • Start date
C

Christopher G. Carnahan

I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and hangs,
or goes into an infinite loop (don't ask why, it just does), then I want to
free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the method
that is blocking. But it doesn't look like that thread actually aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is already
consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing it?

- Christopher
 
N

Nicholas Paldino [.NET/C# MVP]

Christopher,

If the program is your own, then you have to find out what is causing
the loop. Coding around it like this is just going to bring you more
headaches. When you say "don't ask why, it just does", that means that you
either know what the problem is, and refuse to fix it, or you don't know
what the problem is.

Ultimately, there is no excuse for either case.

Regardless, killing the thread that you made the call on isn't going to
help. If you are stuck in an interop call, then calling Abort will not kill
that thread.

Your best bet would be to find the process using the Process class, and
once you have an instance of the Process class representing that process,
call the Kill method on it.

Hope this helps.
 
W

Willy Denoyette [MVP]

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

- Christopher

You do know the .exe file name of the VB6 ActiveX server program do you?
So, you can use System.Diagnostics.Process.GetProcessByName(the.exe name) to
get the corresponding Process instance and kill that one using Process.Kill.
Note that it might be possible that you can't kill the process because you
haven't sufficient privileges to do so. Also note that you should not call
Thread.Abort at all, chances are that you are corrupting your process state,
just reinitiate the client process, or use a separate Application Domain to
run the COM client, when the server hangs you simply throw away the
offending AD and create a new one to restart the client.

Willy.
 
C

Christopher G. Carnahan

I didn't write the component, I know what the problem is, and changing it is not an option (right now).

Finding the process and killing it was my plan, but there's no way to get that information from the COM object or from any .Net framework classes is there? So I have to write code to take the ProgID, find it in the registry, locate the associated LocalServr32 file, and hope that the process name and the .exe name are always the same.

No one has any other options?

- Christopher


Nicholas Paldino said:
Christopher,

If the program is your own, then you have to find out what is causing
the loop. Coding around it like this is just going to bring you more
headaches. When you say "don't ask why, it just does", that means that you
either know what the problem is, and refuse to fix it, or you don't know
what the problem is.

Ultimately, there is no excuse for either case.

Regardless, killing the thread that you made the call on isn't going to
help. If you are stuck in an interop call, then calling Abort will not kill
that thread.

Your best bet would be to find the process using the Process class, and
once you have an instance of the Process class representing that process,
call the Kill method on it.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

- Christopher
 
N

Nicholas Paldino [.NET/C# MVP]

Christopher,

Did you look at the Process class? When your component is running, it has a process name in the Task Manager. Just find out what it is and then use the Process class to get the managed representation of it and then kill it.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
I didn't write the component, I know what the problem is, and changing it is not an option (right now).

Finding the process and killing it was my plan, but there's no way to get that information from the COM object or from any .Net framework classes is there? So I have to write code to take the ProgID, find it in the registry, locate the associated LocalServr32 file, and hope that the process name and the .exe name are always the same.

No one has any other options?

- Christopher


Nicholas Paldino said:
Christopher,

If the program is your own, then you have to find out what is causing
the loop. Coding around it like this is just going to bring you more
headaches. When you say "don't ask why, it just does", that means that you
either know what the problem is, and refuse to fix it, or you don't know
what the problem is.

Ultimately, there is no excuse for either case.

Regardless, killing the thread that you made the call on isn't going to
help. If you are stuck in an interop call, then calling Abort will not kill
that thread.

Your best bet would be to find the process using the Process class, and
once you have an instance of the Process class representing that process,
call the Kill method on it.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

- Christopher
 
C

Christopher G. Carnahan

There's more than 1 component with this problem. I need to find out dynamically what the name of the process is.

- CGC

Christopher,

Did you look at the Process class? When your component is running, it has a process name in the Task Manager. Just find out what it is and then use the Process class to get the managed representation of it and then kill it.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
I didn't write the component, I know what the problem is, and changing it is not an option (right now).

Finding the process and killing it was my plan, but there's no way to get that information from the COM object or from any .Net framework classes is there? So I have to write code to take the ProgID, find it in the registry, locate the associated LocalServr32 file, and hope that the process name and the .exe name are always the same.

No one has any other options?

- Christopher


Nicholas Paldino said:
Christopher,

If the program is your own, then you have to find out what is causing
the loop. Coding around it like this is just going to bring you more
headaches. When you say "don't ask why, it just does", that means that you
either know what the problem is, and refuse to fix it, or you don't know
what the problem is.

Ultimately, there is no excuse for either case.

Regardless, killing the thread that you made the call on isn't going to
help. If you are stuck in an interop call, then calling Abort will not kill
that thread.

Your best bet would be to find the process using the Process class, and
once you have an instance of the Process class representing that process,
call the Kill method on it.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

- Christopher
 
W

Willy Denoyette [MVP]

I suppose that each components is "hosted" in a differently named .exe file, so it' should be possible to associate the component with the .exe and kill that one as explained previously. However, if your components are "hosted" in .exe files each having the same name, you're stuck.

Willy.





There's more than 1 component with this problem. I need to find out dynamically what the name of the process is.

- CGC

Christopher,

Did you look at the Process class? When your component is running, it has a process name in the Task Manager. Just find out what it is and then use the Process class to get the managed representation of it and then kill it.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
I didn't write the component, I know what the problem is, and changing it is not an option (right now).

Finding the process and killing it was my plan, but there's no way to get that information from the COM object or from any .Net framework classes is there? So I have to write code to take the ProgID, find it in the registry, locate the associated LocalServr32 file, and hope that the process name and the .exe name are always the same.

No one has any other options?

- Christopher


Nicholas Paldino said:
Christopher,

If the program is your own, then you have to find out what is causing
the loop. Coding around it like this is just going to bring you more
headaches. When you say "don't ask why, it just does", that means that you
either know what the problem is, and refuse to fix it, or you don't know
what the problem is.

Ultimately, there is no excuse for either case.

Regardless, killing the thread that you made the call on isn't going to
help. If you are stuck in an interop call, then calling Abort will not kill
that thread.

Your best bet would be to find the process using the Process class, and
once you have an instance of the Process class representing that process,
call the Kill method on it.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

- Christopher
 
O

Ole Nielsby

Christopher G. Carnahan said:
I have a C# service that is making regular calls into an out-of-process COM
component written in VB6. Problem is, if the VB component blocks and
hangs, or goes into an infinite loop (don't ask why, it just does), then I
want to free and release it.

When I've decided I'm done waiting for the object to return, I call
Thread.Abort on the thread that created the COM object and called the
method that is blocking. But it doesn't look like that thread actually
aborts.

And of course, the actual process that the component is running in hangs
around, stuck in it's infinite loop. And subsequent Requests for that COM
component will stall forever, right, because the single VB thread is
already consumed by the first infinite loop?

Does anybody have any ideas? Worst case scenario, I need to identify the
process that the VB6 object is in and kill it. But nothing in the interop
library that I can find will identify that process for me? Am I missing
it?

When you create an out-of-process COM object, COM will start the
exe file with a command line switch -Embedding or something like
that. The exe will then register its class factory in the Running Object
Table and COM will use it from there.

Now, say you explicitly start the exe file with -Embedding and
keep the process handle. The exe will register its class factory
in the ROT. After a delay to allow this, you can then create an
instance. COM will try the ROT before it tries starting the exe,
so it will use the process you just started and you can use the
process handle you got to shut it down.

Though I'm not sure what happens to the ROT entry if the server
process gets terminated without being given a chance to unregister.
I don't know if COM will detet it's gone or keep waiting for the
resurrection of the dead.

It might be possible somehow to make an asynchroneous interrupt
and have it unregister the ROT entry... but then again, it might be
easier to get the source and slay the bug that makes it hang.

(I really don't know a **** about interop and shouldn't be answering
questions in this NG, but your problem really seems to be about
killing running COM objects more than it has to do with interop.
No Off topic-bashing intended.)

HTH/ON
 

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