I want to close the program from anywhere, but not use HALT

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)

:slight_smile:

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.

1 Like

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.

3 Likes

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.

1 Like

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.

1 Like

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.

1 Like