Autor Beitrag
Popov
Gast
Erhaltene Danke: 1



BeitragVerfasst: Fr 25.10.02 18:54 
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Fr 25.10.02 19:47 
Schonmal an die Verwendung von Mutex gedacht?

_________________
Ist Zeit wirklich Geld?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: 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

_________________
Ist Zeit wirklich Geld?
Popov
Gast
Erhaltene Danke: 1



BeitragVerfasst: 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:

ausblenden 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?
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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
ausblenden Quelltext
1:
ReleaseMutex					

wenn man sein Programm beendet. Das alles und auch die Alternative über Semaphore und Atoms kann man hier nachlesen:
www.entwickler-forum...VXasH9j9X.5@.ee8c498
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: 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:
ausblenden volle Höhe 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.

_________________
Ist Zeit wirklich Geld?


Zuletzt bearbeitet von AndyB am Sa 26.10.02 12:18, insgesamt 4-mal bearbeitet
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 26.10.02 11:43 
AndyB hat folgendes geschrieben:
Nein.

Du hast natürlich recht. Sorry, mein Fehler. :oops: