Groups | Blog | Home
all groups > dotnet interop > november 2005 >

dotnet interop : Killing an Unmanaged VB6 COM Process from C#


Ole Nielsby
11/1/2005 12:00:00 AM

[quoted text, click to view]

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

Christopher G. Carnahan
11/1/2005 1:37:18 PM
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


Christopher G. Carnahan
11/1/2005 2:00:10 PM
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 [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> wrote =
in message news:uiIYr6y3FHA.1276@TK2MSFTNGP09.phx.gbl...
[quoted text, click to view]
Christopher G. Carnahan
11/1/2005 2:16:52 PM
There's more than 1 component with this problem. I need to find out =
dynamically what the name of the process is.

- CGC

"Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> =
[quoted text, click to view]

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.


--=20
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
"Christopher G. Carnahan" <cgcarnahan@earthlink.net> wrote in =
message news:O1rwl%23y3FHA.3592@TK2MSFTNGP12.phx.gbl...
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 [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> =
[quoted text, click to view]
Nicholas Paldino [.NET/C# MVP]
11/1/2005 4:53:37 PM
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]
- mvp@spam.guard.caspershouse.com

[quoted text, click to view]

Nicholas Paldino [.NET/C# MVP]
11/1/2005 5:13:54 PM
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.


--=20
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
[quoted text, click to view]
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 [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> =
[quoted text, click to view]
Willy Denoyette [MVP]
11/1/2005 10:59:39 PM
[quoted text, click to view]

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.

Willy Denoyette [MVP]
11/1/2005 11:37:17 PM
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.





[quoted text, click to view]
There's more than 1 component with this problem. I need to find out =
dynamically what the name of the process is.

- CGC

"Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> =
[quoted text, click to view]

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.


--=20
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
"Christopher G. Carnahan" <cgcarnahan@earthlink.net> wrote in =
message news:O1rwl%23y3FHA.3592@TK2MSFTNGP12.phx.gbl...
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 [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> =
[quoted text, click to view]
AddThis Social Bookmark Button