Starting App from a netfolder

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
dragancesu
Posts: 568
Joined: Mon Jun 24, 2013 11:53 am
DBs Used: DBF, MySQL, Oracle
Location: Subotica, Serbia
Has thanked: 14 times
Been thanked: 101 times

Re: Starting App from a netfolder

Post by dragancesu » Mon Sep 17, 2018 8:22 pm

Yes, you can. HMG has native support for mysql
Are you know sql?

edk
Posts: 343
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 96 times
Been thanked: 252 times

Post by edk » Mon Sep 17, 2018 8:53 pm

Hi Robert.
My proposal is similar with Apais and Franco, although it may differ in details but it boils down to the same.
The solution proposed by PeteWG unfortunately does not work for me.
Below is a brief example of how I would do it:

Code: Select all

#include "hmg.ch"

PROCEDURE Main

PUBLIC cPath:='', cLoggedDBF:='logged_user.dbf', cLoggedUserName:='', cLoggedFileName

hb_vfOpen( hb_ProgName(), 16 )		//The solution proposed by PeteWG.
MsgBox('Checking solution: hb_vfOpen( hb_ProgName(), 16 )')


cLoggedFileName := cPath + cLoggedDBF
 
IF !FILE( cLoggedFileName )
	dbcreate( cLoggedFileName, {{"USERNAME","C",50,0}} )
	SELECT 333
	USE &(cLoggedFileName)
	APPEND BLANK
	USE
ENDIF

SELECT 333
SET EXCLUSIVE OFF
USE &(cLoggedFileName)
SET EXCLUSIVE ON
cLoggedUserName := Alltrim ( UserName )
IF !FLOCK()
	MsgStop('This application is currently used by ' + cLoggedUserName, 'Access denied.')
	QUIT
ENDIF
REPLACE UserName WITH GetComputerName()
COMMIT

//Open any DBF, but do not close select 333 until the application is finished.

DEFINE WINDOW Servisa ;
   AT 120,120 ;
   WIDTH 400 ;
   HEIGHT 300 ;
   FONTNAME 'ARIAL' FONTSIZE 12;
   TITLE "DATA" ;
   MAIN ;
   ON RELEASE QuitApp()
 END WINDOW

 Servisa.center
 ACTIVATE WINDOW Servisa
RETURN NIL
*********************************************
FUNCTION QuitApp()
//It is not necessary:
//CloseData()	//Close all aliases except 333
//SELECT 333
//REPLACE UserName WITH ''

CLOSE DATA
RETURN
*********************************************
FUNCTION CloseData()
Local i
FOR i := 1 TO 999
	IF i <> 333
		SELECT &i
		CLOSE
	ENDIF
NEXT i
RETURN
Last edited by edk on Tue Sep 18, 2018 8:39 am, edited 1 time in total.

edk
Posts: 343
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 96 times
Been thanked: 252 times

Post by edk » Tue Sep 18, 2018 8:27 am

I was intrigued by the solution proposed by PeteWG:
PeteWG wrote:
Mon Sep 17, 2018 10:06 am
Hi,
probably the most quick (and not dirty, I hope, yet quite strict and inflexible), might be this line of code alone:

Code: Select all

hb_vfOpen( hb_ProgName(), 16 )
Put it on top of your Main() procedure and let the OS be responsible
that only one user at a time will be able to run the program.

It's similar to "semaphore" proposition made by Angel, but it doesn't require
a dummy dfb or something. It's kind of a "self-semaphore-ization" ;)

Note: I have not tested it, but see no reason to not works as expected.
Warning: Be sure your users do not used to have a "two-three hours coffee break", leaving the program running! :-)



regards,
Pete

_____________________________________________________________________________
- “Sir, I exist!”
- “However”, replied the Universe, “the fact has not created in me a sense of obligation”.
(Stephen Crane)

Depending on the source code, sometimes it did not work at all, sometimes it did not work on the second launch, but it worked the next time.
At last I was able to write a code that works right away only on local drives, it does not set the Exclusive mode on network resources.
But I do not know why other attempts (#1, #2, #3) fail :roll:
Tested on Win 10 32 and 64 bit with HMG 3.4.4

Code: Select all

#include "hmg.ch"

PROCEDURE Main
Local fApp

//Attempt #1 
//It doesn't work.
//hb_vfOpen( hb_ProgName(), 16 )

//Attempt #2
//It works only after the third application launch.
//fApp := hb_vfOpen( hb_ProgName(), 16 )

//Attempt #3
//It doesn't work.
//DO WHILE !hb_isPointer(hb_vfOpen( hb_ProgName(), 16 ))
//ENDDO

//Attempt #4
//It works on local devices only
maxAttempts:=1000
nAttempt:=0
DO WHILE .T.
	nAttempt++
	fApp := hb_vfOpen( hb_ProgName(), 16 )
	IF hb_isPointer(fApp) .OR. nAttempt == maxAttempts
		EXIT
	ENDIF
ENDDO
IF !hb_isPointer(fApp)
	MsgInfo('An attempt to set the Exclusive mode failed !')
	QUIT
ENDIF


DEFINE WINDOW Servisa ;
   AT 120,120 ;
   WIDTH 400 ;
   HEIGHT 300 ;
   FONTNAME 'ARIAL' FONTSIZE 12;
   TITLE "DATA" ;
   MAIN 
END WINDOW

 Servisa.center
 ACTIVATE WINDOW Servisa
RETURN NIL
*********************************************

User avatar
PeteWG
Posts: 123
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 4 times
Been thanked: 34 times

Post by PeteWG » Tue Sep 18, 2018 2:28 pm

ROBROS wrote:
Mon Sep 17, 2018 6:58 pm
...
hb_vfOpen() is a harbour function?
Yes it is! Please, take a look here for more...

regards,
Pete

User avatar
PeteWG
Posts: 123
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 4 times
Been thanked: 34 times

Post by PeteWG » Tue Sep 18, 2018 2:53 pm

edk wrote:
Tue Sep 18, 2018 8:27 am
I was intrigued by the solution proposed by PeteWG:
Hi EDK,
Don't strive anymore, to make it work! I'm afraid, it won't!
I must admit that my supposedly "clever" idea of the "self-semaphore-ization" of the executable, failed miserably.
Sadly, that's usually the result of "shooting in the dark"; sometimes you risk to shoot your foot! or your fellow's foot... :-)

Anyway, below is a worked sample, of how a file locking scheme, resembling a "semaphore-like" mechanism,
could be implemented and used for the purpose that ROBROS asked for.

Code: Select all


#include "hmg.ch"
PROCEDURE Main()
   LOCAL pKeyHandle
   DEFINE WINDOW AppWin ;
      AT 120,120 ;
      WIDTH 400 ;
      HEIGHT 300 ;
      TITLE "Semaphorization!" ;
      MAIN ;
      ON INIT (Iif( GetTheConch( @pKeyHandle ), NIL, ;
                   ( MsgExclamation( "No one runs the program unless he's holding the conch!", "No Pasaran!" ), __Quit() ) ) ) ;
      ON RELEASE ( Iif( ! Empty( pKeyHandle ), ;
                   MsgInfo( Iif( hb_vfClose( pKeyHandle ), "Key file closed! That's neat.", "Hmm! cannot close key file. (why?)" ) + hb_eol() + ;
                  "Quitting program...", "Exit" ), NIL ) )
   END WINDOW
   CENTER WINDOW AppWin
   ACTIVATE WINDOW AppWin
   RETURN

FUNCTION GetTheConch( pHandle )
   LOCAL cProgName := hb_ProgName()
   LOCAL cKeyFile := hb_FNameName( cProgName ) + ".key"
   IF (pHandle := hb_vfOpen( cKeyFile, 0x0500 ) ) == NIL
      RETURN (pHandle := hb_vfOpen( cKeyFile, 16 ) ) != NIL
   ENDIF
   hb_vfClose( pHandle )
   RETURN (pHandle := hb_vfOpen( cKeyFile, 16 ) ) != NIL
   
Right now I can't test it on network, only locally on my notebook.
You may want to confirm whether it's working or not.

regards,
Pete

ROBROS
Posts: 132
Joined: Thu May 25, 2017 6:30 pm
DBs Used: DBF
Has thanked: 45 times
Been thanked: 11 times

Post by ROBROS » Tue Sep 18, 2018 6:58 pm

Hi to all,
thank you again for your replies.

@ Edward:
to understand your proposal I first have to learn about 'hb_vfOpen( hb_ProgName(), 16 )'

@dragancesu: in good old dbase you could call 'set sql on'. then you could manipulate dbfs with sql-syntax. I never have used that, I thought it was only for selecting data for reports.
Now you tell me that I can use clipper for UI. That is new to me.

regards
Robert

User avatar
dragancesu
Posts: 568
Joined: Mon Jun 24, 2013 11:53 am
DBs Used: DBF, MySQL, Oracle
Location: Subotica, Serbia
Has thanked: 14 times
Been thanked: 101 times

Post by dragancesu » Tue Sep 18, 2018 7:44 pm

Foxbase had the ability to use sql syntax, clipper did not have this

if someone is interested, they can set up the basics of using HMG with the MySQL database

I started that long ago, maybe it's time to continue...

ROBROS
Posts: 132
Joined: Thu May 25, 2017 6:30 pm
DBs Used: DBF
Has thanked: 45 times
Been thanked: 11 times

Post by ROBROS » Tue Sep 18, 2018 8:14 pm

ROBROS wrote:
Tue Sep 18, 2018 6:58 pm

Now you tell me that I can use clipper for UI. That is new to me.
Sorry, you didn't tell me clipper can be used, but hmg. Many times I use clipper as a synonym for hmg

regards
Robert

edk
Posts: 343
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 96 times
Been thanked: 252 times

Post by edk » Wed Sep 19, 2018 8:23 am

PeteWG wrote:
Tue Sep 18, 2018 2:53 pm
Anyway, below is a worked sample, of how a file locking scheme, resembling a "semaphore-like" mechanism,
could be implemented and used for the purpose that ROBROS asked for.
(...)
Right now I can't test it on network, only locally on my notebook.
You may want to confirm whether it's working or not.

regards,
Pete
Hi Pete.
I checked your Semaphorization in a network environment and it works great. Thanks.

I tested for unexpected program shutdown caused by program execution error or application killing. It looks good.
It seems to me that the operating system releases any file locks made by it after the application is finished.
I did a test: I deleted _vfClose (pKeyHandle) on releasing the application.
The key file lock is automatically released when the application is finished, so in theory it is not necessary to close the key file before closing the application.
However, it is worth doing for clean code :)

Regards, Edward.

User avatar
PeteWG
Posts: 123
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 4 times
Been thanked: 34 times

Post by PeteWG » Wed Sep 19, 2018 10:35 am

Hi Edward,
I checked your Semaphorization in a network environment and it works great. Thanks.
That's good! Now, I'm thinking this function could be extended a little, to do a simple program usage logging,
f.e. by using hv_vfWrite() to keep track and record user name and starting / exiting time. a really plain and easy task.. ;-)
It seems to me that the operating system releases any file locks made by it after the application is finished.
yes! normally, a decent O/S should release any pending file-locking(s), made by a program that has stopped running.
this is particularly critical in case of abnormal termination (crash!) of program that made the locking.
However, you (the reliable programmer) must not depend on O/S in doing your housekeeping! 8-)
(not to mention that older Windows have a notorious history, regarding similar incidents;
I'm sure you'd seen/read, in the past, messages referring to exactly that problem,
about files remaining locked or open after a program crash, accompanied with data loss,
or corruptions and all this "wonderful" things).

regards,
Pete

Post Reply