I ran into an issue using Halt. Is there an alternative?
do you mean a remote close? Nettalk allows that.
Or do you mean the current user?
Or is it just that the Halt window mucked up the close?
Capesoft Messagebox has a replacement with many options, including logging.
I have used TaskKill.exe to terminate the current or all the WinPreview Exeās (made by the Window Designer). This happens inside the Preview program itself, so it does kill the EXE that ran it.
See the CBWndPreview.clw file on GitHub line 4899 the TaskKillRtn ROUTINE. Just do a Find on āTaskKillā ⦠Itās not much code so Iāll paste it:
TaskKillRtn ROUTINE
DATA
BatFN PSTRING(48)
Tm8 STRING(8)
CRLF STRING('<13,10>') !Tests show max length below 350 chars so below PUTINIs safe from 1024 limit
FI_Filter PSTRING(256)
Title STRING(32)
CODE
IF ~GLO:IsPreviewEXE THEN
IF 1=Message(COMMAND('0')&'||This is NOT a Preview EXE.||Do you really want to Halt It?','HALT',ICON:Hand,'Let Run|Halt It') THEN EXIT.
END
Tm8 = FORMAT(CLOCK(),@t05) &'00'
BatFN='.\WinPreviewKill' & Tm8[1:4] &'-'& Tm8[5:8] &'.BAT'
REMOVE(BatFN)
FI_Filter = '/FI "IMAGENAME eq WinPreview*"'
IF SMCmd_wParam=SMCmd_HaltCapt THEN
Title=GloT:Caption
IF Title[1]='"' THEN Title=LEFT(Title[2:32]).
X=INSTRING('"',Title) ; IF X THEN Title=SUB(Title,1,X-1).
FI_Filter=CLIP(FI_Filter) & ' /FI "WINDOWTITLE eq ' & CLIP(Title) &'*"'
END
PUTINI('BAT', 'REM 1 ', |
CRLF & 'TITLE Halt Window Previews' & CHOOSE(~Title,'',' of "' & CLIP(Title) &'*"' ) & |
CRLF & 'ECHO OFF' & |
CRLF & 'COLOR 1E' & |
CRLF & 'CLS' & |
CRLF & 'REM /v slowwww: TASKLIST /v /FO LIST ' & FI_Filter & | !Verbose List above table so can see more details
' | Findstr /ivb /C:"Session" /C:"Mem" /C:"Status" /C:"User" /C:"CPU"' & |
CRLF & 'ECHO+ ' & | !CRLF &'ECHO ={80}' &| !too slow-->
CRLF & 'ECHO+ ' & CRLF , BatFN )
PUTINI('BAT','REM 2 ','Confirm Kill List' & |
CRLF & 'ECHO TASKLIST ' & FI_Filter & |
CRLF & 'TASKLIST ' & FI_Filter & |
CRLF & 'REM ECHO ErrorLevel %ErrorLevel%' & |
CRLF & 'ECHO+' & |
CRLF & 'CHOICE /C:YN /N /T 99 /D N /M "Halt the above Window Previews? (Y/N)" ' & |
CRLF & 'IF %ERRORLEVEL% EQU 2 EXIT /B 666' & |
CRLF & 'ECHO+ ' & CRLF , BatFN )
PUTINI('BAT','REM 3 ','Kill Previews ' & |
CRLF & 'ECHO+' & |
CRLF & 'ECHO TASKKILL ' & FI_Filter & |
CRLF & 'TASKKILL ' & FI_Filter & |
CRLF & '' & |
CRLF & 'REM ECHO ErrorLevel %ErrorLevel% & PAUSE' & |
CRLF & ':EndIt' & |
CRLF & 'DEL %0 ' & CRLF, BatFN )
!if 2=message('BatFN=' & BatFN &'||Path=' & LongPath() &'||' & FI_Filter,,,'Run|Close' ) THEN EXIT.
RUN(BatFN,1)
REMOVE(BatFN)
IF RUNCODE()<>666 THEN HALT(). !User Says NO then BAT does EXIT /B 666
Interesting code trick. I run TaskKill from a BAT file that I create using a PUTINI. It has one bad line [BAT] that errors, but a CLS fixes that.
The above Kill filters on Image Name (EXE Name) WinPreview* with wildcard *. If I just wanted to Kill My Running EXE I would use the /PID # switch that takes the Process ID from GetCurrentProcessId() so there is zero risk of killing the wrong one.
Halt probably calls Windows ExitProcess that tries to shutdown cleanly, but can deadlock (read the notes).
TerminateProcess will āunconditionally cause a process to exitā so is what you could try. I used TaskKill because I wanted to kill multiple EXEs
I use remote close to shut down my software that is running on workstations. Iāve been using Halt for a long time, but all of a sudden itās causing an error. I have a small procedure I call to check if the ācodeā that allows the program to run is good, if it is, it just returns. If it isnāt, it halts. Itās only called at the beginning of running the program. On other areas, I just call the procedure on the same thread, so I get a variable back which then if true, it closes the window, which is the main screen. If thereās no easy way, Iāll just rewrite the check code in a procedure that is not handwritten so I can just call it and return. I tried setting a global variable, but the variable isnāt set yet because Iām starting the procedure. I think Iāll just rewrite it. I wrote this procedure like 20 years ago. But youād think Clarion would have a simple way to shut down the program. It even says in the docs that Halt shouldnāt be used on multi-dll programs. All of a sudden, Iām getting a really ugly error with a bunch of stuff that would scare the crap out of my customers. Before, it would just cleanly exit. I thought there was a program close in one of the tools I have⦠I think I have them all⦠not messagebox though, I had a ton of trouble with it years ago. But Iāll look into it.
Thanks
I think thereās a Clean Close Down Template, you might look into that.
MessageBox hooks the dialogs and Halt and allows you to replace them with your own procedures, so you have lots of control.
I have a feeling that Halt doesnāt necessarily close and remove everything properly, it just stops and exits.
post(event:closedown,1) turns out to work well. In this particular procedure, I close the one file I manually opened, and post to the main thread, which is 1. ChatGPT gave me the answer⦠it gave me a lot of other answers too, this one was at the bottom and worked perfectly for my circumstance.
Thanks for everyones help, it led me in the right direction. (Its actually 2 commas in the post(event:closedown) above. Must be some kind of html thing in this board?
Hi Ray,
Thatās an interesting problem, and you can definitely hit edge cases (for example, a third party template hooking HALT and changing the expected behavior).
I just added two new shutdown helpers to vuFileTools that are aimed at your exact scenario.
vuCloseApp(Mode) gives you three behaviors:
- Mode 0: cooperative close request (normal shutdown). Windows get a chance to close cleanly, but users may still see āsave changesā prompts.
- Mode 1: cooperative close first, plus a safety net. It requests a normal shutdown, then forces termination after a short delay if the app is still running.
- Mode 2: immediate hard kill. No prompts and no cleanup, so unsaved work can be lost.
The other new function, vuCloseAppEx(Mode, KillDelayMS, WarnSeconds), adds two things: you can set the Mode 1 safety net delay, and you can optionally warn users and wait (for example, 30 seconds) before initiating the close so they can save work.
That might be a good fit for you because you can kick people out of the program, but still give them a warning that it is about to happen. If they are at the machine, they can save and close normally. If they walk away from a save prompt, it still exits.
This should work well for situations like āclients launched from a server share and I need everybody out so I can update the EXEā because you can warn them, attempt a clean close, and still guarantee the app exits.
If anyone reading this is not familiar with vuFileTools, the main site is clarionproseries.com and the online function reference is here: https://clarionproseries.github.io/docs/vuFileTools/
I am building the installer now and it should be available soon.
(edit)
The new build is up and you can read about the new functions here:
I hope this helps everyone who needs this sort of functionality!
Charles
You can wrap your Clarion code in two backticks and it will look better and format correctly:
POST(EVENT:CloseDown,,1)
![]()
One more thing about the code you used.
POST(EVENT:CloseDown,,1) works fine as long as you are not sitting in a dirty FORM.
In my testing, if a FORM is open and has unsaved changes, posting CloseDown does trigger the usual āsave changesā prompt, but it may not actually close the application frame afterward.
The reason is that once that prompt is up, the event processing has effectively shifted into the FORM thread/window, so the frame does not necessarily complete its own shutdown sequence.
This is exactly the kind of edge case where a safety net close mode like I just implemented in vuFileTools is useful, because it still attempts a clean shutdown, but guarantees the process exits even if the app gets stuck behind a save prompt.
Thatās also the case thatās handled by MessageBox with a countdown timer.
Iāve been using Nettalk remote shutdown with massagebox for years and it works very well.
If you want to kill program and send an exit code, you can use ExitProcess.
The API is called in this repo, but building a procedure to call it and have the app use this shutdown procedure requires a bit of thinking and changes to the app in general, like Formās to be aborted or saved.
CHAIN with an empty string will terminate the program.
CHAIN(āā)
CHAIN('')
Docs says:
CHAIN terminates the current program, closing all files and returning its memory to the operating system, and executes another program.
Hi Ray,
What error are you getting from HALT()? Is it a compile error or a runtime error?
Best regards,
In this particular instance thereās no danger of that, but in many other cases, your code will work much better (and safer). I appreciate it, and others will to. Iāve had vufile tools forever and use it all the time. Iām glad you took over and glad youāre adding new tools.
Thanks Ray!
Itās a good library of functions and now that I have it in a new build system it is a lot easier to extend and document so Iām sure there will be more goodies added as we go along.
I replaced the closedown with the vuCloseApp(0). It works well. I know itās closing normally because I have a little POP sound when my app closes. Nettalk has a way of shutting down the app over the lan, but I warn people to shut it down manually because Iām not sure if it shuts down correctly on the workstations. Iāll look into that⦠and see if I can replace the shutdown with this.
I think I used mailslot years ago. I built something like a kiosk display where it would show the transaction as it is being processed to the customer on a 2nd screen. In between, it would show ads for the store, which were created by flash files. Too bad theyāre gone. I use the vuMail tool as well.
Thanks for all of your work.
Iām glad it helped out Ray.
Like anything there are multiple ways to get there sometimes and it is usually about finding the one that works best for your needs.
The vuMail template is long in the tooth now since Microsoft deprecated the underlying API and as a result it never got updated to modern security standards. As a result it wonāt connect to many of the more secure servers these days.
But the good news is that weāre almost ready to release a new product that is a drop in replacement for the code called vuMailKit. It is built on modern subsystems that Microsoft recommends for email.
It works with all modern secure servers and even handles OAuth security with ease so it makes your customerās experience easy in that regard too.
Weād hoped to have it out a while back, but decided to take a different approach in making it backwards compatible for vuMail users so we duplicated all 70+ functions in the new code (and added some more for the new features).
Weāre working on the docs and such now and should have the Basic version out in a day or so.
There will also be a Pro version a bit later that gives you IMAP capability as well as an email client that you can rebrand and sell to your customers.
Weāre also working on a Back Office edition that will make it easy to run and manage an email campaign, handle bounces, unsubscribes and mailing lists.