Entwickler-Ecke
Windows API - Feststellen ob Klasse gerade sonst wo benutzt wird
Anonymous - Fr 25.10.02 18:54
Titel: Feststellen ob Klasse gerade sonst wo benutzt wird
Ich schreibe gerade an eine Klasse die das System leicht manipuliert. Dabe werden einige Einstellungen in der Registry verändert. Leider hab ich gerade festgestellt, daß es da zu Problemen kommen wird wenn ein zweites Programm damit gleichenzeitig arbeitet. Die Programme überschreiben sich die Systemeinstellungen gegenseitig . Das Problem ist, daß eines der beiden (oder noch mehr Programme) nicht mehr richtig funktionieren würde. Solange nur eins der Programme läuft gibt es da keine Probleme.
Nun frage ich mich ob man feststellen kann ob gerade eine Klasse im System am laufen ist. So eine Art Auflistung oder Abfrage. Ich glaube es zwar nicht (ich kenne keine Möglichkeit) aber ich kenne so vieles nicht.
Bevor jetzt einer fragt ob das Problem wirklich kommen würde, ich hab bereits drei Programme in dem ich den gleichen Code benutze. Es läßt sich leider nicht anders lösen, da es um Systemeinstellungen geht.
Zwar kann der Windowsuser die Einstellung manuell verändern, aber dann ist er sich im klaren, daß er eine Änderung durchgeführt hat. Mein Programm würde einfach nicht richtig funktionieren.
Ist fast das gleiche wie nur einmal ein Programm starten können.
AndyB - Fr 25.10.02 19:47
Schonmal an die Verwendung von Mutex gedacht?
Delete - Fr 25.10.02 20:28
AndyB hat folgendes geschrieben: |
Schonmal an die Verwendung von Mutex gedacht? |
Dürfte schwer werden, denn so wie ich es verstanden habe sind es nicht seine eigenen Programme, die auf die Schlüssel zu greifen.
AndyB - Fr 25.10.02 20:37
Dann hast du es wohl falsch verstanden:
Zitat: |
ich hab bereits drei Programme in dem ich den gleichen Code benutze |
Anonymous - Fr 25.10.02 21:15
Mutex? Wäre eine Möglichkeit. Leider kenne ich mich in diesem Bereich wenig aus und mein Englisch ist auch nicht so perfekt. Ich hab mir auf die schnelle sowas geschrieben:
Quelltext
1: 2:
| CreateMutex(nil, False, 'IrgendEineBezeichnung'); if GetLastError = ERROR_ALREADY_EXISTS then ShowMessage('Ist schon da'); |
Soweit ich es rausfinden konnte, gibt es einen Fehlecode wenn ein zweites mal CreateMutex mit der gleichen Bezeichnung gestartet wird. Theoretisch funktioniert es also.
Allerdings weiss ich nicht so genau wozu Mutex gut ist. Hat irgendwas mit Threads zu tun, glaube ich. Ich bekomme in solchen Fällen ein mulmiges Gefühl wenn ich mit etwas arbeite was ich nicht 100% verstehe. Mußte zwar richtig sein, aber ich brauche Bestätigung. Muß man da wieder was freigeben?
Delete - Sa 26.10.02 08:29
Ich darf dich beruhigen, Hagen Reddmann aus dem Entwicklerforum sagte, dass Mutexe eine saubere Variante sind. Freigeben sollte man mit
wenn man sein Programm beendet. Das alles und auch die Alternative über Semaphore und Atoms kann man hier nachlesen:
http://www.entwickler-forum.de/webx?128@14.2cVXasH9j9X.5@.ee8c498
AndyB - Sa 26.10.02 11:17
MathiasSimmack hat folgendes geschrieben: |
Freigeben sollte man mitReleaseMutexwenn man sein Programm beendet. |
Nein. Mit ReleaseMutex schaltet man den mit WaitForXxx gesperrten Mutex für andere Threads (auch Prozesse) frei. "Gelöscht" werden kann ein Mutex am Programmende mit CloseHandle().
Hier ist mal eine Mutex-Klasse:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87:
| type TMutex = class(TObject) private FHandle: THandle; FDeleteOnFree: Boolean; FAlreadyExists: Boolean; public constructor Create(const AName: string; CreateLocked: Boolean = False); constructor CreateHandle(AHandle: THandle; ADeleteOnFree: Boolean = False); destructor Destroy; override;
function Acquire(MaxWaitTime: Cardinal = 0): Boolean; procedure Release;
procedure Enter; procedure Leave;
property AlreadyExists: Boolean read FAlreadyExists; property Handle: THandle read FHandle; property DeleteOnFree: Boolean read FDeleteOnFree write FDeleteOnFree; end;
constructor TMutex.Create(const AName: string; CreateLocked: Boolean = False); begin inherited Create; FHandle := CreateMutex(nil, CreateLocked, PChar(AName)); FAlreadyExists := GetLastError = ERROR_ALREADY_EXISTS; FDeleteOnFree := True; end;
constructor TMutex.CreateHandle(AHandle: THandle; ADeleteOnFree: Boolean = False); begin inherited Create; FHandle := AHandle; FAlreadyExists := False; FDeleteOnFree := ADeleteOnFree; end;
destructor TMutex.Destroy; begin if FDeleteOnFree then CloseHandle(FHandle); inherited Destroy; end;
function TMutex.Acquire(MaxWaitTime: Cardinal = 0): Boolean; begin Result := WaitForSingleObject(FHandle, MaxWaitTime) = WAIT_OBJECT_0; end;
procedure TMutex.Release; begin ReleaseMutex(FHandle); end;
procedure TMutex.Enter; begin if not Acquire(0) then raise Exception.CreateFmt('%s is nonsignaled', [ClassName]); end;
procedure TMutex.Leave; begin Release; end;
// Benutzung: var m: TMutex;
procedure Xyz; begin m.Enter; try // geschützter Bereich finally m.Leave; end; end;
initialization m := TMutex.Create('Eindeutiger Bezeichner');
finalization m.Free;
end. |
Beim Einsatz eines Mutex ist der try-finally-Block immer nötig. Sollte nämlich eine Exception auftreten und der Mutex nicht entsperrt werden, dann bleibt das andere Programm stehen ohne das der Benutzer (außer über den Taskmanager) noch mit dem Programm arbeiten kann.
Delete - Sa 26.10.02 11:43
AndyB hat folgendes geschrieben: |
Nein. |
Du hast natürlich recht. Sorry, mein Fehler. :oops:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!