orphaned command line process in Windows 7/RB2011

First, I’m using RealStudio 2011 R1.1.

I’m building a front end to the x264 encoder, which is command-line based. My application works pretty well so far, but I’m unable to cancel the process that’s spawned by my shell object, and with x264 it’s conceivable that a process could use 100% of CPU (or close to it) for 12 or more hours, even on a high end machine. So I need to be able to make this abort button work. Here’s the basic setup:

In my main Window I added a Shell called Shell1. I’ve tried all three modes. I’ve also tried various timeouts including -1 and 0. The “Encode” button in this window calls Shell1, executing x264 with the parameters the user has specified in this window. This all works perfectly. The “Encode” button also enables the “Abort” button. This button has two lines of code as its Action:

Shell1.close
me.Enabled=false

When clicked, this does indeed stop the updating of progress information in the window. However, the Windows Task Manager is showing that the x264.exe process is still running and using almost 100% of the CPU. Once the encode is done, this process terminates on its own, but that can take many hours. the only option is to kill the process manually in the Task Manager.

So I’ve looked through a ton of forum posts (here and elsewhere) and I’m not seeing anything that’s working for me. In addition to the code above, I’ve tried getting the PID from shell1.PID and manually killing that, but it doesn’t match the PID of the process in Windows (RB thinks it’s 1500, but Windows says it’s 3136, for example).

Any suggestions? Is this possible? I’m seeing so many posts with people having this problem, but the only two resolutions I can find aren’t working for me.

[quote=108875:@Perry Paolantonio]First, I’m using RealStudio 2011 R1.1.

I’m building a front end to the x264 encoder, which is command-line based. My application works pretty well so far, but I’m unable to cancel the process that’s spawned by my shell object, and with x264 it’s conceivable that a process could use 100% of CPU (or close to it) for 12 or more hours, even on a high end machine. So I need to be able to make this abort button work. Here’s the basic setup:

In my main Window I added a Shell called Shell1. I’ve tried all three modes. I’ve also tried various timeouts including -1 and 0. The “Encode” button in this window calls Shell1, executing x264 with the parameters the user has specified in this window. This all works perfectly. The “Encode” button also enables the “Abort” button. This button has two lines of code as its Action:

Shell1.close
me.Enabled=false

When clicked, this does indeed stop the updating of progress information in the window. However, the Windows Task Manager is showing that the x264.exe process is still running and using almost 100% of the CPU. Once the encode is done, this process terminates on its own, but that can take many hours. the only option is to kill the process manually in the Task Manager.

So I’ve looked through a ton of forum posts (here and elsewhere) and I’m not seeing anything that’s working for me. In addition to the code above, I’ve tried getting the PID from shell1.PID and manually killing that, but it doesn’t match the PID of the process in Windows (RB thinks it’s 1500, but Windows says it’s 3136, for example).

Any suggestions? Is this possible? I’m seeing so many posts with people having this problem, but the only two resolutions I can find aren’t working for me.[/quote]

Why not track the Windows system process PID through TaskList and kill it with TaskKill ?

I can actually kill the process by name using taskkill:

Shell1.Execute("taskkill /F /IM x264.exe")

This works perfectly. The problem is that my application allows you to choose from multiple builds of x264 that might be on your PC, and those could have different names, so I need to be able to do it by PID or some other link to the specific process that’s running. It’s also conceivable that we’ll add in the ability to run multiple instances of the encoder simultaneously, so calling by name is a bad idea.

When I use tasklist, the PID doesn’t correspond with anything I’m aware of from the RB side of things. That is, the PID from Shell1.PID is some totally different number that doesn’t match up with anything that’s showing in Tasklist. Sure, I could look up the actual system PID for the x264.exe instance, but that puts me in the same situation as I just described - what if it’s a different build with a different name?

Is there a way to get the actual system PID of the spawned process, without searching for it by name?

Or I guess as an ugly hack way to do it, is there a way to “name” a process when executing it? That is, is there a way I can tell Windows to list the instance of x264 for that particular encode with some unique name that I choose, rather than “x264.exe?” If so, I could work around this problem.

Thanks!

[quote=108886:@Perry Paolantonio]This works perfectly. The problem is that my application allows you to choose from multiple builds of x264 that might be on your PC, and those could have different names, so I need to be able to do it by PID or some other link to the specific process that’s running. It’s also conceivable that we’ll add in the ability to run multiple instances of the encoder simultaneously, so calling by name is a bad idea.
[/quote]

Here is the way to know which PID is associated with which copy of x264.exe :

  • Fetch the running processes list with shell to TaskList
  • Out of the result, get the running x264.exe
  • Launch the new x264.exe
  • Shell to TaskList again
  • Compare with the older list and identify the new PID

Do that each time you spawn a new x264.exe and keep a record, so you know which one you want to kill.

Thanks. I’ll give that a try today. I’m also going to try another method I saw which involves launching cmd.exe, naming its window and then having a uniquely named command process within which to launch x264.exe (thus easier to locate and kill if necessary). Both methods seem fairly clunky though, so I wonder why this isn’t something RealBasic/Xojo does natively? Or does it in newer versions?

Thanks!

A guy is drowning and cries for help. A good samaritan throws him a life jacket. The guy says “I don’t like orange. Do you have the same in pink”?

I appreciate the help, and if this is what I have to do, I will. But really, I’d rather not resort to workarounds if I can help it.

It’s a reasonable question to ask why I can’t seem to simply and elegantly kill a process spawned by my application without having to build in all this extra tracking code - I’d expect that an instance of Shell would have some mechanism for destroying spawned processes built-in. If Shell.Close() doesn’t do the job, ok. But the documentation implies that it does: “Shuts down the running command.” So I think it’s reasonable to question what’s going on and why there isn’t a cleaner method of ending a process that an application might spawn. If there isn’t, so be it.

No need to take it personally, though.

Just tried to help with a tested solution. Sorry you did not like the color.

The Shell.PID property is NOT a process ID number; it’s a process handle. You can pass Shell.PID directly to TerminateProcess. https://forum.xojo.com/6243-force-quit-a-shell-windows/p2#p46099

To get the process ID pass Shell.PID to the GetProcessID api function.