PDA

View Full Version : Solved: I Wanna Kill! a process



Wizard
12-11-2005, 08:23 PM
Situation: Using Excel 2000 to control another program (IBM Personal Communications) to communicate with our mainframe, and while the connecting (as an Object, named "PComm" for this thread) & sending commands is no problem, I just have difficulty letting go. No, this is not better suited for 'Dear Abby'...

When the job is complete, I use a "Set PComm = Nothing" command to release the object.

Now... this works absolutely fine on my computer with Personal Communications v5.6, but my company is upgrading the computers it will be used on to (very nice) hyperthreaded machines with Personal Communications v 5.7.

On the new machines, the first time Personal Communications is accessed, it works perfectly. The next time, however, it (PComm) hangs when the VBA procedure tries to link with Personal Communications. It hangs hard, too - I have to go into Task Manager & end the tasks (both PComm & Excel, which won't do anything while waiting for the linkup), then go to the next tab & kill the PComm processes - there are 2 sets of them at that point. Either that or reboot. Then start everything back up, and it will work perfectly again - once.

I've tried a number of ways around this in VBA, but so far I have had no luck.

I have researched this and found that it is apparently caused by a combination of the hyperthreading capabilities of the new machines and the software, which causes a DLL to not unload properly. From the IBM site http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1IC39146 (http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1IC39146):

After a VBScript macro is played in a PCSWS process (pcomm
session), the EHLLAPI dll, pcshll32.dll, is not getting
unloaded. When one of the PCSWS processes is closed, the dying process sets a variable to False in pcswlib.dll. Later when the same PCSWS process unloads all the dlls, pcshll32.dll is also unloaded during which it waits for this same value to be set to True. This causes a deadlock and results in PCSCM as well as other PCSWS processes to hang.
Though admittedly the problem they describe elsewhere on that page isn't exactly what we are experiencing, it is similar enough to lead me to believe this is the issue.

One fix suggested on that site is to disable the hyperthreading in the BIOS on the machines in question. I think this would be simple enough to do on one machine to show whether or not we're barking up the right tree, but of course, I would have to climb pretty far up IT's... tree to get that done.

The other is to update the software. This is a global $8+Billion (sales) company and while I have turned that over to the IT department, things like this in a company this size can tend to move slowly. I don't have that kind of time.

As, at least, a temporary fix/workaround, what I need to be able to do is to programmatically kill the processes for PComm, forcing the application to close. The user would then have to restart that application & re-log in, but that's a lot less painful than rebooting, and a lot less risky than teaching the users to muck about killing processes thru Task Manager.

I've had the suggestion to initialize a variable as a process, so I could then get the open processes and close the appropriate ones, but the object library thing that allows me to Dim a variable as a Process is missing, apparently. Or maybe I just haven't been able to find it....

Clues, anyone?

: pray2:

Killian
12-12-2005, 07:51 AM
Hi there,

It would be quite useful if you could test what happens on the new HT hardware running v5.6 and the old hardware running 5.7 - that way you can determine where the problem is actually occuring.

I have to admit I'm not at all familiar with IBM Personal Communications but I had a quick look at some documentation and the Automation class seems quite extensive.
I have a couple of questions:
How to you create the instance of the app from Excel (I'm assuming something like "Set PComm = New someclassname")
How do you quit it and is there a way to get a return value from this call?

On face value, it would seem that v5.7 now implements some kind of requirement that didn't exist in v5.6, say cleaning up a child object, thread or process that was previously self-terminating.

The link you gave from IBM seems to me to be talking about VBScript run from a PCSWS process, which is not the case here (Personal Communications appears to have all kinds over scripting features available)
Disabling the hyperthreading isn't exactly a solution (at least not to a company that's just bought a pile of hyperthreading PCs) but a useful test to run if you still can't pinpoint the source of the issue.

In terms of a temp fix, if it comes to that, what you will need to do is either:
before you quit Excel (or the workbook) is check to see if the process is still running and kill it or Create and terminate the process yourself.
You can use WinAPI calls to do either but I'd be inclined to try to get to the root of the issue since having to find and destroy left-over processes is not recommended.

mvidas
12-12-2005, 08:38 AM
Consider me subscribed to the question

I've never actually had this issue before (though I only use v5.5 of personal comm.), my issue is the memory usage problems. Try running a long .mac file that is coded in vbs, and try not to get the memory to it's limit. Even setting objects to nothing in every instance (which I've done) doesn't seem to get to all of it, I eventually just gave up and just deal with the stupid problems it gives me. My best method (I can try helping you if need be) is not to use VBA to do this, but a .vbs file to open a new pcomm.auteclconnmgr connection (as well as a pcomm.auteclsessionsession).

One thing that gave me the biggest help in dealing with the memory issue is the order in which you set items to nothing. If I set my connection manager variable to nothing before i set my session variable to nothing, pcsws.exe stays in my task manager and has to be manually killed. But if I set the session = nothing before the connmgr, I have less problems.

In any case, using the pcomm objects sounds like it will never be perfect, but at least they do work. And I've found that teaching people how to kill processes via the task manager is an easy enough thing. But as Killian says, it is easy enough to do via code with APIs as well, if thats really the route you want to go.

Matt

Ken Puls
12-12-2005, 03:58 PM
I don't have the app you guys use, but was intrigued by the question. I remember that Mark007 made a kb entry to Check if a process is running. It doesn't include code to actually kill the process, but I'm sure that either Killian or Matt can probably add that part.

HTH,

lucas
12-12-2005, 05:55 PM
Marcster has an API entry called "Terminate running process" in the kb forum thats ready for approval(almost). His example shuts down all running instances of notepad.exe. Might be worth a look. It will be approved as soon as I hear from him.

Killian
12-12-2005, 05:58 PM
I don't have the app you guys use, but was intrigued by the question. I remember that Mark007 made a kb entry to Check if a process is running. It doesn't include code to actually kill the process, but I'm sure that either Killian or Matt can probably add that part.

HTH,
Well that's half the job done, I've added a little more code to get a handle to the process and terminate it (run sub "test" in module2)

It still feels far from an ideal solution. One particular pitfall in not accounting for the possibility of pre-existing instance of the app before you come along and kill it with your code.

Zack Barresse
12-13-2005, 12:54 AM
To list all processes (thanks to NateO), create a userform with a listbox, populate it with something like this ...

Sub lstAllProcess()
'Derived from procedure found here
'http://visualbasic.ittoolbox.com/documents/document.asp?i=1975
Dim AppsRunning As Object
Dim myApp As Object
Dim Wnmgts As Object
Set Wnmgts = GetObject("winmgmts:")
Set AppsRunning = Wnmgts.InstancesOf("win32_process")
For Each myApp In AppsRunning
Debug.Print myApp.Name
Next
Set AppsRunning = Nothing
Set Wnmgts = Nothing
Set myApp = Nothing
End Sub

Other very GOOD related information:
http://msdn.microsoft.com/msdnmag/issues/0400/wmi/
http://vb.mvps.org/samples/project.asp?id=TaskList
and the start of another thread over at MrE here..
http://www.mrexcel.com/board2/viewtopic.php?t=184149

HTH

mvidas
12-13-2005, 05:54 AM
Wizard,
Try running the following, it should close any/all open client access sessions:Sub WizardClosePComm()
Dim autCon As Object, i As Long
Set autCon = CreateObject("pcomm.auteclconnmgr")
autCon.autECLConnList.Refresh
'autCon.StopConnection "A" 'if you know the session name you could use this syntax too
For i = 1 To autCon.autECLConnList.Count
autCon.StopConnection autCon.autECLConnList(i).Name
Next
Set autCon = Nothing
End SubBy the way, if you haven't seen this page, you must bookmark it:
http://publib.boulder.ibm.com/infocenter/pcomhelp/index.jsp?topic=/com.ibm.pcomm.doc/host_access08.htm
Every script I've built has come from information from that page about the pcomm object.

Matt

Wizard
12-13-2005, 09:51 AM
Killian:
Virtually no chance of cross-checking the hardware/software combinations as you suggested... I don't work in IT & they keep the machines pretty well locked down.
Later note: One of the users has an IBM laptop like mine instead of the new hyperthreaded boxes, but is running PC v5.7 - and it works fine for her.

When I close, it's just
Set PComm = Nothing
So I don't think there's any way to get a return value.

You said "check to see if the process is still running and kill it or Create and terminate the process the process yourself. You can use WinAPI calls to do either."

I am stupid again today... Just how does one do that?
:dunno

mvidas:
Well, one consideration is that I don't have VB proper, only VBA, so no .vbs files.

You mentioned opening a new pcomm.auteclconnmgr connection and a pcomm.auteclsession session - that's not the way I've been doing it (lack of eddication shows itself here). I've been setting up my session like so:
Set PComm = GetObject("C:\Program Files\IBM\Personal Communications\private\profile.ws")
PComm.SetConnectionByName ("A")


and then when I close, it's just
Set PComm = Nothing


Thanks to you both, even tho we don't have a solution yet....

mvidas
12-13-2005, 10:04 AM
mvidas:
Well, one consideration is that I don't have VB proper, only VBA, so no .vbs files.The code I posted above was actually designed for VBA, not vbs. And (though it doesn't matter in this case) if you have windows2000+ you have vbs on your computer :)


You mentioned opening a new pcomm.auteclconnmgr connection and a pcomm.auteclsession session - that's not the way I've been doing it (lack of eddication shows itself here). I've been setting up my session like so:
Set PComm = GetObject("C:\Program Files\IBM\Personal Communications\private\profile.ws")
PComm.SetConnectionByName ("A")


and then when I close, it's just
Set PComm = NothingYou don't have to have a connection manager with the session variable, just the session variable should work fine. Before setting PComm to nothing, try the line PComm.StopCommunicationsee if that closes it first. If not, you'll have to do something along the lines of: Dim autCon As Object, PComm As Object
Set autCon = CreateObject("pcomm.auteclconnmgr")
autCon.StartConnection "profile=profile.ws connname=A"
Set PComm = CreateObject("pcomm.auteclsession")
PComm.SetConnectionByName "A"So later you can useautCon.StopConnection "A"to close the session. Don't forget to set autCon to nothing at the end as well.
Matt

Killian
12-13-2005, 03:56 PM
Hi Wizard,
from what you say it sounds like Matt is pointing you in the right direction.
"Set PComm = Nothing" just clears the variable - you need to find a way stop the app's activity using the PComm object before you do that (closing connections etc).
Something (like an open connection) will be running as a thread from the PComm app process and if it seems to be an issue only with hyperthread CPUs, I'm tempted to speculate that the HT controller may require all threads to be appropriately terminated from the parent process.

Wizard
12-15-2005, 10:42 AM
The simpler method that Matt proposed worked on my system, but again, not on the new machines.

The code you (Killian) posted above, however, worked just fine. I have to make a couple passes as there are 2 processes that have to close, but I think this will work.

I'm going to mark this as solved, and my thanks to all for your help!!

mvidas
12-15-2005, 11:15 AM
Glad we could help, and it sounds like I should be glad I'm using v5.5! :)