TPIPE problem

#1
With this line in my otherwise empty TCEXIT.BTM (or TCSTART.BTM)
Code:
SET /U /A TCCCount+=1
the command below shows its output immediately but the prompt doesn't return for about 40 seconds. If, during that time I try to interrupt with Ctrl-C, TPIPE.EXE crashes and after I say "Close the program, I get a message box:
Code:
Error
Runtime error 217 at 00011D18
OK
and the TCC instance is crippled thereafter.
 
#3
Much more simply, and probably related, with the one line "SET /U /A TCCCount+=1" in TCEXIT, there is a 5 second delay after clicking the console's "X" and before TCC terminates. If I remove "/U" all's OK. Can't access the registry during TCEXIT?
 
#5
You never showed the "command".
Oops! It was this.
Code:
v:\> type "http://forecast.weather.gov/MapClick.php?CityName=Syracuse&state=NY&site=BGM&textField1=43.0446&textField2=-76.1459&e=0" | tpipe /grep=3,0,0,1,0,0,0,0,"point-fore.*High|point-fore.*Low" /simple=16 /selection=7,0,2,2,0,5,"&",0 /simple=19 /replace=0,1,0,1,0,0,0,0,0,"Low: ","Low:  "
High: 22
Low:  17
High: 36
Low:  35
High: 47
Low:  42
High: 55
Low:  31
High: 35
 
#6
Much more simply, and probably related, with the one line "SET /U /A TCCCount+=1" in TCEXIT, there is a 5 second delay after clicking the console's "X" and before TCC terminates. If I remove "/U" all's OK. Can't access the registry during TCEXIT?
And the variable is not incremented. And this remains so if I load no plugins (/IP).
 
#7
Much more simply, and probably related, with the one line "SET /U /A TCCCount+=1" in TCEXIT, there is a 5 second delay after clicking the console's "X" and before TCC terminates.
My guess would be that TCC itself does not respond to the WM_SETTINGSCHANGE message which it (itself) generated as a result of "SET /U". Is it good old-fashioned deadlock? I'd guess there's a way around it since EXIT works OK (when clicking the "X" doesn't).
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#8
Not that it should matter, but have you tried the TCC syntax instead of the CMD syntax?
Code:
set /u TCCCount=%@inc[TCCCount]
echo %@regset[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
echo %@regsetenv[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
-Scott
 
#9
Not that it should matter, but have you tried the TCC syntax instead of the CMD syntax?
Code:
set /u TCCCount=%@inc[TCCCount]
echo %@regset[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
echo %@regsetenv[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
-Scott
Yes. The first of those above misbehaves as I have described. The second is the one I'm using; it works OK.
 
#10
Code:
set /u TCCCount=%@inc[TCCCount]
echo %@regset[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
echo %@regsetenv[HKCU\Environment\TCCCount,REG_DWORD,%@inc[TCCCount]]
Yes. The first of those above misbehaves as I have described. The second is the one I'm using; it works OK.
And the third of those above works OK.
There's something amiss. Of @REGSETENV, the help says "The same as @REGSET, but a broadcast message is sent to all applications when the change is made". But checking with a new CMD started by Explorer suggests no message was sent; a new CMD does not get an updated environment after TCC has
Code:
ECHO %@REGSETENV[HKCU\Environment\TCCCount,REG_SZ,%@INC[%@REGQUERY[HKCU\Environment\TCCCount]]]
On the other hand, the help for "SET /U" makes no mention of broadcasting a message but a message is broadcast. New CMDs started by Explorer do get an updated environment after TCC has
Code:
SET /U TCCCount=%@INC[%TCCCount]
 

rconn

Administrator
Staff member
May 14, 2008
10,495
94
#11
Much more simply, and probably related, with the one line "SET /U /A TCCCount+=1" in TCEXIT, there is a 5 second delay after clicking the console's "X" and before TCC terminates. If I remove "/U" all's OK. Can't access the registry during TCEXIT?

This is a complicated scenario with no simple solution -- and what's happening is probably not what you think is happening.

When you click on the "X", the system sends a WM_ENDSESSION to the message handling window that TCC creates for itself (otherwise, like other console apps, TCC would not be able to intercept or respond to those messages). Upon receipt of the WM_ENDSESSION, TCC calls the EXIT command. Your TCEXIT.BTM is opened, and the "SET /U ..." line is executed. That eventually triggers an HWND_BROADCAST / WM_SETTINGCHANGE message, which is required to use the SendMessageTimeout API. (It cannot use something like PostMessage because it has to pass a pointer in LPARAM.) The SendMessageTimeout API is passed a 5-second timeout, and it starts calling all of the top level windows.

Eventually, the TCC window is called -- but it cannot process the message, because it's still in the WM_ENDSESSION message. (If TCC did something like a ReplyMessage() in the WM_ENDSESSION call, TCC would terminate immediately without being able to run TCEXIT.) So Windows waits 5 seconds, decides that TCC isn't going to process the WM_SETTINGCHANGE message, and continues notifying the other top-level windows. At roughly the same time, Windows also decides that TCC isn't going to return from the WM_ENDSESSION, so Windows summarily terminates TCC.

So -- the moral of the story is don't do things in your TCEXIT that require nested message handling in the console window. (Or stop clicking on "X" to close TCC!)

Alternatively, I could reduce the timeout for SendMessageTimeout to something less (one second?), though I suspect you'd then file a bug that TCC takes a second to exit after clicking "X" with a SET /U in TCEXIT. :dead:
 
#12
That's what I figured (in principle, anyway); thanks for the details. I can live with that.

But there remains the fact that that @REGSETENV[HKCU\Environment\...] either doesn't broadcast any message or broadcasts one which fails to make Explorer (just for example) update its environment (as Explorer does when I "SET /U").

This is a complicated scenario with no simple solution -- and what's happening is probably not what you think is happening.

When you click on the "X", the system sends a WM_ENDSESSION to the message handling window that TCC creates for itself (otherwise, like other console apps, TCC would not be able to intercept or respond to those messages). Upon receipt of the WM_ENDSESSION, TCC calls the EXIT command. Your TCEXIT.BTM is opened, and the "SET /U ..." line is executed. That eventually triggers an HWND_BROADCAST / WM_SETTINGCHANGE message, which is required to use the SendMessageTimeout API. (It cannot use something like PostMessage because it has to pass a pointer in LPARAM.) The SendMessageTimeout API is passed a 5-second timeout, and it starts calling all of the top level windows.

Eventually, the TCC window is called -- but it cannot process the message, because it's still in the WM_ENDSESSION message. (If TCC did something like a ReplyMessage() in the WM_ENDSESSION call, TCC would terminate immediately without being able to run TCEXIT.) So Windows waits 5 seconds, decides that TCC isn't going to process the WM_SETTINGCHANGE message, and continues notifying the other top-level windows. At roughly the same time, Windows also decides that TCC isn't going to return from the WM_ENDSESSION, so Windows summarily terminates TCC.

So -- the moral of the story is don't do things in your TCEXIT that require nested message handling in the console window. (Or stop clicking on "X" to close TCC!)

Alternatively, I could reduce the timeout for SendMessageTimeout to something less (one second?), though I suspect you'd then file a bug that TCC takes a second to exit after clicking "X" with a SET /U in TCEXIT. :dead: