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!

Timer in executable on network

Status
Not open for further replies.

Puebles

Programmer
Feb 3, 2016
14
US
Hello,

I have an issue of users leaving a program running for days. This prevents me from updating table structures, indexes, and issuing an updated executable. I have put a timer on the main screen which checks to see if I have set a variable in the "Control" table which should trigger a shutdown. The timer and shutdown works flawlessly in the VFP development environment. However, when run as an executable from the server the timer does not fire.

OK, I just amended this post after finding an article that explains that timers do not run in an executable. So, my new question is "How do I force a shut down?"

Your feedback is appreciated.
 
>timers do not run in an executable
That's wrong, they do.

A better setup is a central exe stored as ._xe file and write a .cmd or .bat file with copy \\servershare\foo._xe to c:\vfpexes\bar.exe -- c: -- cd \vfpexes\ -- start bar.exe . That way you can always update the central foo._xe file, as it's never started.

In regard of updating DBCs needing exclusive access, that is a hard problem, unless you make your changes by creating a new database folder with empty dbc and append all data into the new structure (an ALTER TABLE does that anyway, creates a new file and appends the data of the old dbf/fpt) You just have the disadvantage users only get updates, when they restart the batch file.

Finally indeed it is a good interest to have a way to shutdown running apps by eg a timer. It depends on the code in it, though, and how you define the timer. There should be nothing modal like a MESSAGEBOX() without timeout telling the user the EXE will shut down, it will never get to the next line, for example. I don't think you have something like that in your code, but something less obviously not shutting down the exe, when it should.

Bye, Olaf.

 
I have an executable running at several hundred locations which has a timer checking for the existence of a file named "quitnow.flg", once a second. If it sees that file (which I have put in a particular location), it forces the executable to shut down. So yes, timers work. And that's how I force users out of the application.


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
I agree with the others. Like many developers, I have implemented automatic shutdowns in my applications. There's certainly no problem in using timers from an executable.

I suggest you take this step by step. Create a very simple executable; add a timer; and check that it fires. Then start adding the logic to read the "shutdown" signal, and perform the actual shutdown. That way, you will find whether you are making some mistake in using the timer, or if your problem occurs somewhere else.

Keep in mind that this sort of automatic shutdown system is always more complicated than people think. You need to think about how you are going to warn the user that he is about to be kicked out and to give him the opportunity to save his work; of dealing with the situation if he fails to save his work (safely rolling back any transactions and reverting any buffers); dealing with a new user logging in after the warning period has started; and giving the administrator some sort of emergency override in case there is a critical process in operation that must not be interrupted.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Very good thoughts, Mike. You might also implemnent a mechanism not reacting to a shutdown signal, but only exiting idle instances. Then some things are simpler, but you have to deal with an application in a modal state. Eg a messagebox, also if not coming from the timer, hinders a QUIT to quit the process. You might use an approach using Windows API ExitProcess, which can exit the app forced, too. In a clean exit you'll want to save curtrent transactions and such, though, that even applies to inactive users having left their cllient in the midst of an editing session.

Bye, Olaf.
 
Olaf said:
You might use an approach using Windows API ExitProcess

Yes, that's exactly what I do - but only after rolling back transactions and reverting buffered data. Some developers would object to that, because it means losing unsaved edits, but we're talking about an exceptional situation (where a user has gone home and, not only left the application running, but left it in mid edit).

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks all. I will keep trying then.

I have about 40 users. All but two are read only. The two with write capabilities are my co-worker and me. So, I am not worried about shutting people down. Plus I precede the closing (attempt) with emails asking people to shut down. The updated executable will show me who has not logged off, but no luck replacing it so far.

I have tried a basic timer per MSDN examples and it works. I tried the same in my program and it works in the VFP Development environment. However, when compiled it does not work. I have tried other examples I have found to no avail. Am I placing it properly?

The program allows the user to select from 7 different classifications of records. Each class has at least one table, some have many. There are a total of 22 tables. All tables display in grid format on the MAIN screen. For all tables users can view detail using 7 different view screens based on classification. For three classifications, 11 tables, users can edit detail, and print documents based on permission using three edit screens. So there is _screen, Main, 7 view screens, and 3 edit screens. I have placed the timer on MAIN. If someone is accessing other screens they are performing a check against the shut down code with each action. I am looking for those that leave the program running. Does the timer belong on _screen? If so, how is it put there?

I have read that some have had a problem of instantiating the timer. Wouldn't that happen on screen load?
 
>Am I placing it properly?
How can we say that, if we don't know how you place it? What's your code?

Just having a timer class in your code doesn't start it. You have to put a timer on a form or create one with CREATEOBJECT or with .ADDOBJECT method or such. The same, that you have to do, whn using a timer in the VFP IDE.

Bye, Olaf.
 
Whatever experiments you do in _SCREEN doesn't get compiöled into an EXE. _SCREEN is not part of your pjx file, it's just part of the VFP ide and runtime. _SCREEN can be a place of your timer, but a timer doesn't need to be added to any object, you can also use a global variable to hold the timer or add it to your goApp object.

Bye, Olaf.
 
I have placed the timer on MAIN. If someone is accessing other screens they are performing a check against the shut down code with each action. I am looking for those that leave the program running.

As long as your Main form is running, the timer should fire - assuming you have correctly set the Interval property, and you have valid code in the Timer event. That's true even if Main is not the active form. But if the user closes Main, the timer will not fire.

But are you sure you have understood the nature of the timer? You say your are looking for users who "leave the program running". A timer doesn't do that. And is that what you want?

The way an automatic shutdown works is for an administrator to set up a flag of some kind when he wants people to shut down. The flag might be an empty file sitting in a pre-determined directory, or it might be a logical field in a given record, or anything else that all users can access. Each user has a timer in their instance of the program. When the timer fires, it looks for the flag. If it is set, a warning is displayed, stating that the system will shut down in so-many minutes, and they should save their work immediately. Then a second timer is set, and this fires when the warning period expires.

This is not the same as testing to see whether the program is running, or whether the user is actually doing anything. The system I have described will fire regardless of what the user is doing - even if the user has gone home for the night. Nor does it make sense to send an email to the user. Better to pop up a system modal message on the user's screen, in front of all their other windows. That will give you the best chance of the user seeing the message and taking the necessary action. If they are busy working in the application, they might not check their email, or they might miss seeing your message.

I know this doesn't answer your original question. But you do need to think through how the process is going to work, and how the timer will be used.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Olaf said:
Whatever experiments you do in _SCREEN doesn't get compiöled into an EXE. _SCREEN is not part of your pjx file

This is confusing.

_Screen is always present, even with SCREEN=OFF in config.fpw. It's the one truly global variable and I use it all the time to store values or objects that should survive a CLEAR ALL when dealing with legacy code left behind by previous developers.

Do not stumble over this.
 
What works and how it works depends on your coding, Mike. You can also set the timer to a large interval and with every action reset it (oTimer.Reset()), so finally, when the timer event runs, it may shutdown the exe.

I have placed the timer on MAIN. What do you mean with this? Is the timer enabled?

Bye, Olaf.
 
Dan,

I understand Puebles has expermeinted adding a timer to _SCREEN within the VFP IDE. But that doesn't make the timer on the _SCREEN part of the EXE he builds. The _SCREEN always exists. But it's not the current state of the IDE _SCREEN, that is compiled into an EXE, it is the _SCREEN as is, a blank form. If you do _SCREEN.addobject("timer1","mytimerclass") within the IDE, you only get the _SCREEN.timer1 object in an executable, if you add this line of code into your executable, Puebles seemed to expect the timer has become part of _SCREEN and so it's in the EXE.

Bye, Olaf.
 
Puebles, I think the best thing you can do at this point is to go back to my earlier suggestion: build a simple executable, containing a timer and not much else. Never mind what the timer does. It could, for example, display a messagebox. If you focus on getting that to work, it will help you to understand the nature of a timer and how it should be used.

Once you've done that, it should be easy to figure out what you were doing wrong in your main application.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi,

Below just a sketch how you could code this.

Code:
oForm = CreateObject("Form1")
oForm.AddObject("tmrCloseForm","tmrTimer")
oForm.AddObject("lblMessage","lblLabel")
oForm.Show
Read Events

DEFINE CLASS Form1 As Form

	AutoCenter = .T.
	Name = "frmRandom"
	Caption = "Random"
	MinWidth = This.Width
	MinHeight = This.Height
	
	PROCEDURE DESTROY
		Close All
		Clear Events
	ENDPROC
	
ENDDEFINE

DEFINE CLASS lblLabel AS Label
	Visible = .T.
	Top = 90
	Left = 6
	Caption = "Hi - this form closes in 10 seconds"
	Autosize = .T.
	Fontsize = 18

ENDDEFINE 

DEFINE CLASS tmrTimer as Timer
	Enabled = .T.
	Interval = 10000
	
	PROCEDURE Timer
		This.Reset
		
		lnMessage = MESSAGEBOX("Your app will close in 3 seconds - or click cancel", 1 + 64, "Exit App", 3000)
			IF lnMessage != 2
				oForm.Destroy()
			ENDIF
	ENDPROC 
			

ENDDEFINE

hth

MK
 
I place a logical variable in Control.dbf to affect shutdown in two methods:
1. Every action requires a method to be run to update the main screen: which of 22 tables is showing, and which buttons, check boxes, etc. are appropriate. So, anyone using the program will shut down immediately upon triggering the method. This works perfectly.
2. A timer is placed on the main screen with the following relevant settings: Enabled = .T., Interval = 1000 (Which will be set higher when it works), and Timer Event=

If Control.Logout=.T.

Wait Window Control.Message At 30,20 Noclear Timeout 10

Wait Clear

Thisform.Release

Clear Events

Endif

This works when I run it in Development on my PC, but not when run as executable on the network.

When I copied and tried the code provided by MJCMKRSR it works, as all examples do. It also worked as an executable. My screen is already complete and was created graphically, rather than programmatically as the example. I tried fitting the timer code into the screen and launching routine. I either get no result or the program does not load.
 
In the test that you described, did the timer actually fire? In other words, did you see the Wait Window?

If not, it could be because Control.Logout was not physically set to .T. There might be some buffering or caching at work in the program that sets it - either within VFP or at the Windows level. I once saw exactly that problem in one of my applications. The only way I could see to get round it was to buffer the control table (even though I wasn't writing to it), and using CURVAL() to check its value.

But you don't have to go that far to ascertain if the timer fires. Simply put your Wait Window before your test of Control.Logout. If you see the Wait Window, the timer is firing.

If the above indicates that your timer is firing, and if you are correctly detecting Control.Logout, then there might be something wrong with the actual closedown process. In that case, you should check there is nothing there that might interfere with the closedown, such as an open object reference, or a modal form active.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The timer event has to be in the timer.timer() event, there is no other place for it. I still don't see what exactly you do where. How do you start the timer. Do you get any error messages? Do you have an error handler?

If nothing happens, the most probably reson is Control.Logout is never .T.

So, if you want to check, whether the timer runs without depending on any other prerequisites, for a first test simply do a WAIT WINDOW 'Timer' Timeout 0.5 in the timer event (since the Interval is 1000 you shouldn't have a timeout longer than the interval).

The way you do it, you have 10 timer events triggered, before the timeout of the first Wait Window happens.

Bye, Olaf.
 
Well you sir are a genius. I placed the message box above the check against the shutdown variable (Control.LogOut) and the timer is firing. Makes sense now. I changed the buffering several times and get various responses. So, I think I am going to switch to the method I have heard others use; placing a shut down file in a specific location.

Thank you much.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top