Force-quit a Shell (Windows)

Does anyone know how to force quit a Shell in Windows? Calling the Shell.Close method does not seem to accomplish this. RealStudio 2012 R1.1

What happens if you set the Shell to Nil?

Brilliant. Thanks, Paul. Don’t know why I didn’t think of that before! sigh! haha.

Actually, no, that’s not working at all. I’m totally stumped at this point.

Try sending a ChrB(3) to the shell. I suspect that you have a long running app that you started in the shell that’s holding it open.

Still doesn’t seem to work.

What I’ve got is a print control that spawns a thread that has a shell, the thread executes the shell (in this case, calling the printhtml.exe utility to print an html document to a printer), but the shell never closes/quits even after successfully printing the document. So when the program quits, there’s still a ton of cmd.exe and printhtml.exe’s still running in the processes.

What if you send an “exit” as part of the shell.execute:

theShell.Execute "printhtml.exe " + args + " & exit"

Still nothing. Here’s the shell command

“C:\Users\dougc\Documents\RealBasic Projects\labnet2\DebugLabNet201x\resources\printhtml.exe” file=“C:\Users\dougc\AppData\Local\Temp\00000001891870988196.tmp” printername=“ZDesigner LP 2844” & exit

and it’s just hanging in the task manager processes. The document printed fine.

Now this is sounding like a bug. I had seen something like this many revisions ago, but I thought that it had been fixed.

I recommend that you submit a feedback report on this issue.

In the meantime, how would I get around it? Force-quit the PID of anything matching “printhtml.exe”?

I checked out the process in the resource monitor for the multipe printhtml.exe instances and they all indicated they were waiting for Splwow64.exe in the wait-chain.

This might be it… http://support.microsoft.com/kb/2815716

“Splwow64.exe process doesn’t end after a print job finishes in the 64-bit version of Windows 7”

That would definitely explain what you’re seeing. Until all of the bits of the chain exit, the shell is effectively still running. Scrub creating a feedback report…

At least MS has a hot fix available…

I’m going to install any updates as of today, restart, try again, and if still failure, then try the hotfix, and report back.

Unfortunately neither worked, and I am discovering a multitude of users via google that also have problems with this.

The only solution I can see is to force quit the applications… would you happen to know where to point me as to how to figure out what the PID of the processes are and force-quit them problematically?

Even the hotfix didn’t resolve this?

Quick and dirty hunch : call your shell from a threaded batch script. Then the batch script would be the owner of the processes, right ?

Pass the Shell.PID property to this method (Win32 only):

Function KillProcess(ProcessID As Integer, ExitCode As Integer = 0) As Integer
  Declare Function OpenProcess Lib "Kernel32" (DesiredAccess As Integer, InheritHandle As Boolean, ProcessId As Integer) As Integer
  Declare Function TerminateProcess Lib "Kernel32" (ProcessHandle As Integer, ExitCode As Integer) As Boolean
  Declare Function CloseHandle Lib "Kernel32" (Handle As Integer) As Boolean
  Declare Function GetLastError Lib "Kernel32" () As Integer
  Const PROCESS_TERMINATE = &h1
  
  Dim pHandle, lasterr As Integer
  pHandle = OpenProcess(PROCESS_TERMINATE, False, ProcessID)
  lasterr = GetLastError()
  
  If lasterr = 0 And TerminateProcess(pHandle, ExitCode) Then
     lasterr - GetLastError()
    Call CloseHandle(pHandle)
  End If
  
  Return lasterr
End Function

Doug,

Did you try the following (from: http://support.microsoft.com/kb/2815716):

To Configure a timeout value for SPLWow64.exe

Click Start, and then click Run.
Type regedit, and then click OK.
Locate and then right-click the following registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print
Point to New, and then click DWORD Value.
Type SplWOW64TimeOutSeconds as the registry entry name, and then press Enter.
Double-click the SplWOW64TimeOutSeconds entry that you created in step 4.
Enter a value in the Value data box, and then click OK.

IMO terminating the process would be a last resort option.

[quote=44910:@Andrew Lambert]

lasterr - GetLastError() [/quote]

Should be:

     lasterr = GetLastError()