Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Remote Shutdown VFP 7

Status
Not open for further replies.

RFanslow

Programmer
Jul 16, 2014
24
US
I have been approached by a client, looking for ways to shut down a vfp executable which is sitting at a menu
it never fails that several users leave the app open and files are open which need to be closed for maintenance.

while I don't believe there is a timer function on a main menu, does anyone have a work around as users are located in 3 states using a wan/lan to a main directory on the server.

Any Idea's...

Fanz
 
Hi Fanz, and welcome to the forum.

What your client is suggesting is quite a common requirement. I have a similar feature in several of my applications.

In summary, this is what you need to do:

1. Give the administrator a facility for initiating the closedown. This might involve creating a small file somewhere in the file system (the file doesn't have to contain anything in particular), or changing a logical field in a given table.

2. Within the application, create a timer that fires say, once every five minutes. The timer should check for the presence of the above file, or check the logical field, or whatever.

3. If the check succeeds, display a prominent message to the user, warning that the system will close down in, say, ten minutes, and advising them to save their work. Then set another timer, to fire at the end of that interval.

4. When the second timer fires, have it do the following: (i) roll back all open transactions; (ii) revert all unsaved buffers; (iii) close all open forms; (iv) quit the app.

There are a few additional details that you need to think about. The administrator must be able to cancel the shutdown procedure after the warning has been given; don't allow any new users to log in during the warning period; but DO allow the admin to log in.

That should give you a start. Feel free to come back with follow-up questions.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
There is nothing inbuilt, that can break a modal state, eg a messagebox left open.
But you can always kill a process or unlock files. There are administrative tools for that matter, eg Task Manager in the simplest case. Unlocker.exe is for file unlocking, there are others.

I wouldn't necessarily approach this from inside VFP, though I use a timer to check for application shutdown requests which are made by a flag in a table. This timer looks for the state all 5 Minutes. But it can't quit Messageboxes with Quit, too. In the end it depends on defensive programming, eg always using the timeout for messageboxes.

A menu in a state to choose from it's items was never a problem with our customers users, though. Does that cause a modal state, where Quit won't quit? Does it stops timer events, really? That could be tested. It won't matter much in detail, as there are several modal states, another one is a report in preview, I think. So in the end you perhaps better make use of the ability to kill a process from outside.

Bye, Olaf.
 
Thanks for the reply, I do have an event, actually a
Class, which gets called and instantiated...

But never fires, as it is always at a menu, I seem to recall menus can't fire an event

************************************************
*//--EPO REMOTE / MASTER SHUTDOWN
************************************************
*!* PUBLIC goShD
*!* SET CLASSLIB TO SHUTDOWN
*!* goShD=createobject('PowerShutDownTLF')
*!* goShD.ShutDownWaitTime=3*60*1000 && shutdown wait time 3 minutes
*!* goShD.Interval=60*1000 && check every 1 minute
*!* goShD.ShutDownHandler='FINISH'
*!* goShD.TaskShutDownFile='E:\GISMO\SHUTDOWN.EPO'
*!* goShD.SystemShutDownFile='E:\GISMO\SHUTDOWN.SYS'
*!* goShD.Enabled=.T.
************************************************



PowerShutDownTLF is a simple timer class

local loAlarm
this.AlarmMess=createobject('AlarmWindowTLF')
loAlarm=this.AlarmMess
loAlarm.Inform.Value=this.Inform
loAlarm.MaxValue=this.ShutDownWaitTime
loAlarm.ParentRef=this
loAlarm.Show()
loAlarm.Start()


While I call this object in my setup code before launching the menus..
it never fires, as again I seem to recall menues can't fire times...

So I am looking for something to either close after 10pm PST or a file sitting in a directory, etc...

Fanz
 
it never fires, as again I seem to recall menues can't fire times...

It's not a question of a menu firing a timer. The timer exists independently of the menu. The fact that the application is showing a menu when the timer is due to fire is irrelevant.

You need to create a custom class, which is a sub-class of the native timer class. It is that class that checks the flag and performs the various steps of the shutdown. Then, in your main program, at the start of the session, instantiate the class, using CREATEBOJECT(). The timer will then always be active, and will fire at the specified interval, regardless of what state the application is in.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Olaf,

Regarding your point about modal states:

One way to deal with that is to use the following code:

[tt]DECLARE Integer ExitProcess IN WIN32API
ExitProcess()[/tt]

That will kill the application stone dead, regardless of what the UI is doing at the time - including message boxes, report previews, and other modal things.

Of course, it's important to roll back transactions and revert buffers before taking such a drastic action.

Another reason to use this method is that will avoid having to close individual forms, which risks executing code in QueryUnload, Destroy, etc., given that such code might interfere with an unattended shutdown. For example, a form's QueryUnload might prompt the user to save unchanged edits, causing the shutdown to fail.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
As Mike already pointed out, timers are active from the point you start and enable them.
The code you posted is commented (being prefixed with *!*), the timer isn't created and started. Is it really just that?

Bye, Olaf.
 
For one client I used a non-VFP 3rd party tool called WhoHasNT ( )

With the 'Single License' version I was able to identify who had the application running (so that their boss could be notified about their negligence) and I could shut down the application (or merely close open files that were being used).

Good Luck,
JRB-Bldr
 
Olaf

I clearly wish it was that simple
I have added simple ?"" comments at several line through the startup code, so whil it see the code running thru and it show the object gets loaded, it "Never Fires"

? "Bckgrnd Load Line 18 "
PUBLIC goShutDown
SET CLASSLIB TO FanzRemote additive
goShutdown=createobject('Close')
? "Bckgrnd Load Line 23 "

Close Object is a simple timer on a form....
timer Event [Below]
? "Timer Fired " + Dtoc(Date()) + " " + Time()
thisform.Visible=.t.
This.Interval=0
If File("e:\gismo\shutdown.gsp")
Thisform.Visible=.T.
Thisform.lbl.Caption="IT EPO System Shutdown Required " + Chr(13) + Chr(10) + " Please logout, system is shutting down in 30 seconds"
Do While x<500000
x=x+1
? x
Enddo
Clear Events
Quit
Else

Endif
This.Interval=60000
thisform.Visible=.f.


I really ont see anything in the menu build that would stop this timer from firing...

Grasping for thoughts

Fanz
 
Why are you concerned about the menu?

If your app is in a state doing nothing, it's not it's menu, which is active, the program pointer is at the "READ EVENTS" line, then. And timers running get their event triggered every interval. You should not set Interval=0 and back to 60000, you should rather set Enabled= .f. temporarily during the timer event and you should use the timer.Reset() method to reset the interval, if at all. It's rather a method used from outside of the timer to reset the internal countdown to the full interval.

Perhaps that would help with the timer to work.

Could you simply let the timer write a line to a log file with the current datetime() and check the log, whether the timer event didn't ran?

Also, I mentioned modal states several times already, the occur, when a modal form runs, eg a Messagebox. You still get timer events running, but eg a CLEAR EVENTS has no effect until the modal form ends, which normally means the user has to close it. When there is no user, your Clear Events doesn't end the application.

Bye, Olaf.
 
Olaf

initially i used the interal back to zero so i could debug...

In a debug mode this works perfectly writing the time out to the foxpro screen
im really now sure why it does not fire in the EXE mode

While i here you saying the menu has nothing to do with it, but once the app is on full swing sitting waiting for the client/user
the event does not fire
 
Guys, remember the version here. Prior to VFP8 (IIRC), having the sysmenu open would prevent timers from firing.

My question here is whether the user has opened the menu or you've done something to make it always open. THAT would make the application prone to never shutting down.
 
Close Object is a simple timer on a form....

Why? What we are suggesting is that you instantiate the object within your startup program, and keep it active throughout the application. That's not the same as putting it on a form. If it's on a form, then the timer will never fire unless the form is open.

By the way, "close" is not an ideal name for an object, as it is a VFP keyword. It's unlikely that is causing any problems in this case, but it's something to keep in mind.

While i here you saying the menu has nothing to do with it, but once the app is on full swing sitting waiting for the client/user the event does not fire

I can repeat only what we have already said. Just because the app is waiting for the user, that does not mean the menu is causing the problem. At this point, the menu might be the centre of the user's attention, but as for as the app is concerned, it's simply something that happens to be on the screen.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hey Fanz, long time no hear!

Anyway, I have used Mike's suggestion of a timer looking for the existence of a particular file and QUITting the app if it's there. But I've also had issues with timers in W7, as I mentioned in this thread:
Timer control issue
thread184-1712158

If you can't get the timer to work withing VFP, maybe you could use the windows scheduler with PSKILL.EXE from SysInternals.
As long as you have sufficient permissions on the user's PC, it can kill processes remotely.



-Dave Summers-
[cheers]
Even more Fox stuff at:
 
>initially i used the interal back to zero so i could debug...
Help topic on the interval says "The default value is 0, which prevents the Timer event from firing.", so it's ok, but so is Enabled = .f. and reset to .t. later. It's more commonly used, as it's called - well - enabled.

> I seem to recall menues can't fire times
This matches what dan says. So I made a test and it turns out what I said earlier is true, the timer events happen, just both clear events and quit don't work. Any modal state the app is in, when the timer event tries to clear event and quit does hinder these to work directly.

Here is a test sample:
Code:
Public goShutdownTimer
goShutdownTimer = CreateObject("ctmrshutdown")
Read Events

Define Class ctmrshutdown as Timer
   iRepeats = 10
   Interval = 500
   
   Procedure Timer()
      This.Enabled = .F.
      ? "ran at",Datetime()
      
      This.iRepeats = This.iRepeats - 1
      If This.iRepeats<0
         Clear Events
         Quit
      EndIf
      
      This.Enabled = .T.
   EndProc
EndDefine

Starting this it quits.

Starting this and opening a menu without choosing a menu item it doesn't quit.

Are you sure users do this? Then they have to know this behaviour and use it intentionally, don't they?

So a menu which simply is in place doesn't hinder a timer, even a menu in the state of being used doesn't, the timer keeps printing to the screen. The clear event and quit just don't have any effect until you finally choose a menu item or close the menu by clicking elsewhere.

This is just one of the states keeping a VFP app running and both clear events and quit not having any effect. It's not the only thing. A Messagebox put instead of the read events also doesn't hinder the timer event, but the quit doesn't work. So any Messagebox you display - for example Messagebox("done"), to signal a long running process finished - hinders the clear events and quit to work. You need to avoid any modal states and if you can't prevent that, use all options to make the modal state temporary only, as does the timeout parameter of the Messagebox.

Or you exit the process from something outside of your application.

Bye, Olaf.




 
Olaf, you're assuming there IS a READ EVENTS. :)

There are still some (misguided) people who put ACTIVATE MENU in a loop and call it a day. No amount of fiddling with a timer will help them, which is why I mentioned the problem with active menus.

Of course, neither of us would actually use QUIT or CLEAR EVENTS in a timer method. Rather, we'd call a method of the app object to perform a normal cleanup and exit.
 
Dan,

Yes, we've seen a bad menu code not long ago in thread184-1730025, where it even was a while loop.

As Fanz timer event ends in Clear Events and Quit in case of a shutdown, I assume there is a READ EVENTS.

I also just said the behavior is the same, if you do a Messagebox(), which could be put instead of the READ EVENTS, or any modal main form. CLEAR EVENTS then surely has no effect, but also still QUIT only quits after you close the messagebox.

Bye, Olaf.
 
Dave said:
If you can't get the timer to work withing VFP, maybe you could use the windows scheduler with PSKILL.EXE from SysInternals.

The problem with that approach is that it doesn't give the VFP program the opportunity to clean itself up - to rollback transactions, revert buffers, etc.

Olaf said:
Starting this and opening a menu without choosing a menu item it doesn't quit.

I think we've established that it's not the timer that's causing the problem, but what happens after the timer fires. The timer will fire even in a modal state (which includes an open menu). The problem is that QUIT (or CLEAR EVENTS and then QUIT) might not work. That's either because of the modal state, or because the QUIT could fire a whole chain of events, any of which can prevent the app from closing. I gave an example earlier of a QueryUnload event that prompts the user to save any unsaved edits; if the user has gone home, the form will sit on the prompt indefinitely, and the app won't close.

That's why I use ExitProcess() in these circumstances. I know it's controversial; you need to use it carefully. But it is pretty well guaranteed to work.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

I agree to your conclusion to use ExitProcess(), eg after the QUIT, in case it doesn't already quit the application.

Bye, Olaf.
 
...I tested ExitProcess() with the Messagebox() and you can't put it last to work. You have to do it before QUIT. If you really would like to do it as a last resort, you'd need to trigger it to run delayed, eg start a cmd file which uses PSKILL after a TIMEOUT command, giving VFP a chance to QUIT before PSKILL kills it.

Bye, Olaf.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top