.NET Forum / .NET Framework / Interop / November 2005
Killing an Unmanaged VB6 COM Process from C#
|
|
Thread rating:  |
Christopher G. Carnahan - 01 Nov 2005 22:37 GMT 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
Nicholas Paldino [.NET/C# MVP] - 01 Nov 2005 22:53 GMT 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.
 Signature - Nicholas Paldino [.NET/C# MVP] - mvp@spam.guard.caspershouse.com
>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 [quoted text clipped - 17 lines] > > - Christopher Christopher G. Carnahan - 01 Nov 2005 23:00 GMT 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
> Christopher, > [quoted text clipped - 37 lines] >> >> - Christopher Nicholas Paldino [.NET/C# MVP] - 01 Nov 2005 23:13 GMT 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.
 Signature - Nicholas Paldino [.NET/C# MVP] - mvp@spam.guard.caspershouse.com
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... > 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 > > "Christopher G. Carnahan" <cgcarnahan@earthlink.net> wrote in message > news:eFfVyxy3FHA.1396@TK2MSFTNGP12.phx.gbl... >>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 - 01 Nov 2005 23:16 GMT 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] - 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> wrote in message news:uiIYr6y3FHA.1276@TK2MSFTNGP09.phx.gbl... > 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 > > "Christopher G. Carnahan" <cgcarnahan@earthlink.net> wrote in message > news:eFfVyxy3FHA.1396@TK2MSFTNGP12.phx.gbl... >>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 >> >> >> > >
Willy Denoyette [MVP] - 01 Nov 2005 23:37 GMT 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
"Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> wrote in message news:u7K4AGz3FHA.4076@TK2MSFTNGP15.phx.gbl... 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] - 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> wrote in message news:uiIYr6y3FHA.1276@TK2MSFTNGP09.phx.gbl... > 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 > > "Christopher G. Carnahan" <cgcarnahan@earthlink.net> wrote in message > news:eFfVyxy3FHA.1396@TK2MSFTNGP12.phx.gbl... >>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 >> >> >> > >
Willy Denoyette [MVP] - 01 Nov 2005 22:59 GMT >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 [quoted text clipped - 17 lines] > > - 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.
Ole Nielsby - 02 Nov 2005 01:45 GMT >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 [quoted text clipped - 15 lines] > 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
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|