Seite 1 von 1

Programm sperren

Verfasst: Do, 10. Sep 2015 16:45
von Jojo
Hallo zusammen,

habe mal wieder ein Problem...

Ich möchte einen Programmteil während der Benutzung für andere User sperren.

Dazu habe ich eine Variable t_est deklariert...

Code: Alles auswählen

t_est := ''
, welche zuerst abgefragt wird:

Code: Alles auswählen

do case
case t_est = 0
@ 1,10 say 'Programm gesperrt!'
wait(20)
return ( .f. )
endcase

t_est = 0

Programmablauf...

t_est = 1
.

Weshalb bekomme ich einen Runtime error "data type mismatch in equals '= or ==' operation" ?

Hat jemand eine Idee, bzw. eine bessere Idee, wie ich ein Programm während der Benutzung für andere sperre?

Grüße
Jojo

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 16:49
von mini990
Du weist der Variablen t_est einen Characterwert zu : t_est= ''
Danach fragst Du numerisch ab.
Daher der Datentypfehler...

Gruß Stefan

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 17:07
von Jojo
Hallo Stefan,

und wie weise ich der Variablen einen nummerischen Wert zu?

Grüße
Jojo

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 17:10
von Jojo
O.K., dass war blöd gefragt...

Das ich mit t_est = 1 einen Wert zuweisen kann ist mir klar... :-)

Aber, wie weise ich der Variablen einen nummerischen Wert zu, ohne diese zu definieren?

Grüße
Jojo

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 18:33
von Wolfgang Ciriack
Das wird so nicht klappen, denn jeder PC betreibt sein eigenes Programm und somit auch seine eigenen Variablen.
Ohne einen Wert in einer gemeinsam zugänglichen Datei (Datenbank oder andere Datei) wirst du nicht weiterkommen.
Erzeuge einfach beim Start des Programms eine leere Datei (z.B. InUse.myprog) und behalte sie offen, bis der Programmteil beendet ist, dann schließe und lösche Sie. Beim Start des Programms versucht du nun die InUse.myprog zu löschen. War es erfolgreich oder sie existiert nicht, dann kannst du in das Programm rein, ansonsten ist es in Benutzung.
Ich mache das so um zu ermitteln, wer und wieviele Benutzer mit meinem Programm arbeiten und so eine Benutzeranzahl einzuhalten. Klappt sehr gut, selbst wenn das Programm abstürzen sollte, dann kann die Datei eben gelöscht werden, da sie ja nicht mehr vom Programm offengehalten wird.

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 19:47
von AUGE_OHR
Jojo hat geschrieben:Dazu habe ich eine Variable t_est deklariert...

Code: Alles auswählen

t_est := ''
, welche zuerst abgefragt wird:

Code: Alles auswählen

do case
case t_est = 0
@ 1,10 say 'Programm gesperrt!'
wait(20)
return ( .f. )
endcase

t_est = 0

Programmablauf...

t_est = 1
.

Weshalb bekomme ich einen Runtime error "data type mismatch in equals '= or ==' operation" ?
die Frage ist in welcher Zeile der Fehler gemeldet wird ?

p.s. eine Zuweisung "sollte" man mit := machen während = für einen Vergleich gedacht ist.

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 20:05
von Jojo
Hallo Wolfgang,

das werde ich versuchen und Rückmeldung über den Erfolg (oder eben auch Misserfolg ;-)) geben.
Vielen Dank!

@ Jimmy: Der "Type mismatch-Fehler" wird bei der Zeile "case t_est = 0" gemeldet.

Grüße
Jojo

Re: Programm sperren

Verfasst: Do, 10. Sep 2015 21:43
von Rolf Ramacher
oder du löst das ganze über eine Datenbank in der du Information einträgst

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 10:33
von satmax
Schnellschuss: mit
case t_est == 0
vergleicht man.

case t_est = 0 kann je nach Compilerlaune eine Zuweisung oder ein Vergleich sein.


Achja, auf Datentyp achten:
nicht t_est := '' sondern t_est := 0 // oder 1

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 10:41
von brandelh
Wenn mehrere laufenden Programme eventuell noch auf verschiedenen Rechnern aufeinander reagieren sollen, kann man das nur durch Sperrung externer sachen erledigen.
Mutex oder Semaphore sind Schlagworte in die Richtung, für uns viel einfacher ist eine DBF, die geshared geöffnet wird, und für den Ausschluß anderer einen FLOCK() verwendet.
In der DBF mit einem Datensatz schreibt der sperrende seinen Rechnernamen, alle anderen können lesen wer sperrt, aber sonst nix tun.
Ein Absturz des sperrenden Rechners würde die Sperre automatisch aufheben.

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 10:51
von Tom
Äh. Bei Mutexen geht es um Prozesssynchronisation (Zugriff auf gleiche Speicherbestandteile aus unterschiedlichen Applikationen). Wir sprechen hier aber von unabhängigen Arbeitsplätzen. "Semaphore" ist da das korrektere Stichwort.

Im einfachsten Fall erzeugt man eine Flag-Datei, die anderen Instanzen signalisiert, dass sie derzeit nicht starten dürften (oder sich sogar beenden, wenn sie gefunden wird). Die Flag-Datei - also die Semaphore - wird gelöscht, wenn der Prozess beendet ist. Zusätzlich muss es die Möglichkeit geben, sie von anderswo zu löschen, wenn der Prozess gescheitert ist oder es zu einem Fehler kam.

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 11:03
von satmax
Habe einfach zu wenig genau gelesen. Das mit Zuweisung und Vergleich wurde ja schon gesagt. Ja, das mit den Semaphore mache ich genau so. Es wird eine Datei angelegt und gelockt. So lange diese Date existiert und nicht gelöscht/gelockt werden kann ist gesperrt. Stürzt das Programm das den Lock auf die Datei hat ab, wird der Lock vom Betriebssystem automatisch freigegeben.

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 11:04
von brandelh
Tom hat geschrieben:Wir sprechen hier aber von unabhängigen Arbeitsplätzen. "Semaphore" ist da das korrektere Stichwort.
da bin ich mir aus der Aufgabenstellung nicht so sicher, ein Terminalserver der mehrere Anwender bedient läuft auch auf der gleichen Maschine ...
Die Aufgabenstellung ist da - finde ich - ungenau, aber egal wie, ich würde es eh über die Dateisperre machen :-)

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 11:54
von Tom
Oh, diese Lösung würde ich gerne sehen, wie mehrere Instanzen einer Anwendung auf einem Terminal Server über Mutexe kommunizieren. :wink: Machbar ist es sicher.

Eine Semaphorendatei ist tatsächlich die simpelste Lösung. Man muss nur darauf achten, sie wirklich wieder zu löschen, und ggf. Mechanismen bereitstellen, die das von außen oder beim Versuch eines Programmstarts erlauben (Admin darf es, keiner sonst oder so). Ergänzend sollte sie eine Gültigkeit haben. Eine Semaphorendatei von vorgestern sollte heute nicht mehr das Programm sperren. Das sind insgesamt vielleicht zwanzig Zeilen Code mit allem Pipapo.

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 14:15
von mini990
habe sowas vor Jahren mal auf diesem Weg gelöst:
Beim Programmstart wird abgefragt ob die Datei "InUse" existiert.
Wenn nicht:
Das startende Programm schreibt eine kleine Textdatei "InUse"
Beim Beenden wird die Datei gelöscht.
Fertig.
Hat funktioniert....

Gruß Stefan

Re: Programm sperren

Verfasst: Fr, 11. Sep 2015 14:26
von brandelh
Das mit Datei schreiben und löschen hat früher einwandfrei funktioniert, aber seit die Dateisysteme entscheiden,
wann sie tatsächlich nachsehen oder nur cache Daten liefern ist das nicht mehr zuverlässig.

Ein FLock() auf eine offene DBF ist noch (relativ) zuverlässig ;-)

Re: Programm sperren

Verfasst: So, 13. Sep 2015 16:53
von Jojo
Hallo zusammen,

hier die "angedrohte" Rückmeldung...

Nachdem das mit der Variablen nicht funktionierte und ich (ehrlich gesagt) nicht wusste, wie ich eine Datei erzeuge :-( , habe ich eine im Programm bereits des Öfteren verwende Variante gewählt.

Ich habe eine erfassung.dbf angelegt und frage diese am Anfang ab...

Code: Alles auswählen

select 7
use erfassung
 do while ! rec_lock( 2 )
    k_warn(' ABRUCH! Es wird momentan erfasst!' )
    RETURN( .f. )
 enddo

Programmablauf...

dbclosearea(7)
Damit bekommt ein User, während ein anderer in der Erfassung ist, die Meldung das er nicht weitermachen kann und alles ist i.O. :-)

Einzig das Problem bei einem Programmabsturz, bekomme ich so nicht im Griff.
Beim Testen habe ich gemerkt, das wenn ich ohne korrekten Abschluß aus dem Programm gehe, die Erfassung gesperrt bleibt.

Aber da es sich um einen Programmabschnitt handelt, der nur im sehr seltenen Notfall zum Einsatz kommt, kann ich damit leben, außerdem kann ich ja auch aus der Ferne eingreifen.

Vielen Dank an alle für die, wie immer, hilfreichen Tipps. :-D

Grüße
Jojo

Re: Programm sperren

Verfasst: Mo, 14. Sep 2015 8:27
von brandelh
Jojo hat geschrieben:ich (ehrlich gesagt) nicht wusste, wie ich eine Datei erzeuge
In Xbase++ ich meine das ging auch schon bei clipper ...

Code: Alles auswählen

if ! file(cSteuFile)
   aStru := { { "PCID","c",20,0 } }
   dbcreate( cSteuFile, aStru )
endif

Re: Programm sperren

Verfasst: Mo, 14. Sep 2015 10:29
von Wolfgang Ciriack
Hier mal einfacher Ablauf mit beliebiger Datei (ungetestet). Hat den Vorteil, das es auch bei einem zwischenzeitlichem Absturz des Programms funktioniert.

Code: Alles auswählen

d:="InUse.myprog"
if (nFH:=ChkProgFree())>0
... meine Procedure.....
    FClose(nFH)
    FErase(d)
else
    *** gesperrt
endif

function ChkProgFree(d)
if FExist(d)
   FErase(d)
endif
if FExist(d)
   * Existiert noch immer (konnte nicht gelöscht werden, da in Benutzung)
   ** Programm gesperrt
 endif
nFH:=FCreate(d)
return nFH

Re: Programm sperren

Verfasst: Mo, 14. Sep 2015 10:30
von Tom
Ansonsten auch MemoWrit(), die Low-Level-Funktionen (FCreate u.ä.) sowie StrFile() aus den Tools. Alle wären auch dazu in der Lage, Binärdaten zu schreiben.

Re: Programm sperren

Verfasst: Mo, 14. Sep 2015 10:58
von brandelh
Jojo hat geschrieben: Einzig das Problem bei einem Programmabsturz, bekomme ich so nicht im Griff.
Beim Testen habe ich gemerkt, das wenn ich ohne korrekten Abschluß aus dem Programm gehe, die Erfassung gesperrt bleibt.
Bei Clipper und Xbase++ wird eine offende Datei definitiv geschlossen, wenn das Programm abstürzt.
Dabei werden auch alle LOCKS auf die Datei aufgehoben.

Ich kann mir nicht vorstellen, dass das bei Flagship anders sein soll !

Re: Programm sperren

Verfasst: Mo, 14. Sep 2015 18:11
von Wolfgang Ciriack
@Hubert,
er meint, wenn er in der Datenbank "in Benutzung" gesetzt hat und dann das Programm abstürzt, dann bleibt natürlich in der DBF das erhalten. Deswegen auch mein Vorschlag, mit einer geöffneten Datei.

Re: Programm sperren

Verfasst: Di, 15. Sep 2015 8:46
von brandelh
"In Benutzung gesetzt" ... ok wenn er das über einen Feldinhalt regelt muss es schief laufen.
Ich meinte die Steuerung über die Dateisperre zu regeln

Code: Alles auswählen

use logfile shared alias LOG NEW // am Programmanfang, immer offen, NEW öffnet unter Xbase++ in leerem Select-Bereich
...
IF LOG->(FLock()) // NICHT irgendwelche NET... lock Konstuktionen, weil wir genau einen Versuch möchten !
   // Ich konnte sperren, also darf ich als einziger darauf schreiben
   replace LOG->RechnerID with netname() // so könnte man den Rechner speichern der zuletzt Schreibrechte erhalten hat
   LOG->(dbGoBottom())
   LOG->(dbGoTop())
   ...
ELSE 
   // Fehlgeschlagen, es muss schon in bearbeitung sein 
   ? "Datei in Bearbeitung auf: " + LOG->RechnerID
ENDIF 
Sobald das Programm abstürzt, werden alle Dateien geschlossen und die Bearbeitung automatisch freigegeben.

Re: Programm sperren

Verfasst: Mo, 07. Dez 2015 19:29
von Leon
Tom hat geschrieben:Ansonsten auch MemoWrit(), die Low-Level-Funktionen (FCreate u.ä.) sowie StrFile() aus den Tools. Alle wären auch dazu in der Lage, Binärdaten zu schreiben.
Bei StrFile() aus den Tools scheint es einen Bug zu geben. Unter Windows 8.1 und Windows 10 wird zwar eine Datei erstellt, allerdings mit der Länge 0 Bytes und natürlich ohne Inhalt.

Re: Programm sperren

Verfasst: Mo, 07. Dez 2015 20:51
von Wolfgang Ciriack
Kann ich nicht bestätigen, bei mir klappt es, benutze es öfters ohne Probleme.