Autor Beitrag
s-hus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 11:21 
Hallo zusammen!
Bin noch ziemlich frisch in der Delphi Programmierung und habe folgendes Problem:
Ich öffne Dateien über ein Delphi Programm und will sperren, dass die Datei mehrfach geöffnet werden kann. Das klappt auch einwandfrei bei normalen Anwendungen, bei Verknüpfungen kann ich jedoch beliebig viele öffnen, ohne das Delphi eine Fehlermeldung rausgibt.
Hier der Programmcode:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
begin
  hFile := CreateFile(pchar(ProgrammPfad), GENERIC_READ or GENERIC_WRITE or GENERIC_EXECUTE,
                    0nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Pruef := hFile = INVALID_HANDLE_VALUE;
  if  Pruef = True then
  begin
    ShowMessage('Das Programm ist bereits geöffnet');

    CloseHandle(hFile);
  end else
  begin
    CloseHandle(hFile);
    ShellExecute(0nil, PChar(ProgrammPfad), nilnil , SW_SHOWNORMAL);
  end;

Dieses ist der Teil, der den Mehrfachstart unterbinden soll.
Ich hoffe ihr könnt mir helfen :-)

Einen lieben Gruß.
hazard999
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: Mi 28.11.07 11:28 
Hallo,

probiers mal mit einem Mutex, so mach ich sowas immer.
(Einschränkung: geht nur per Machine, nicht Netzwerkweit)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
   Mutex := CreateMutex(nil, True, 'MyMutex');
   TmpLastError := GetLastError;

   if (Mutex <> 0and (TmpLastError = 0then // Mutex noch nicht vorhanden
   begin
   end
   else
      showMessage('Programm bereits gestartet!');


und beim Programm beenden

         if (Mutex <> 0then
            CloseHandle(Mutex);


r u

René

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 11:30 
Mit einem Mutex hatte ich es auch schon probiert, aber leider Probleme beim einbauen in den Code gehabt :oops:
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 11:41 
Jetzt habe ich anscheinend irgendeinen Fehler eingebaut, denn nun sagt er mir IMMER, dass das Programm schon gestartet sei. Ich habe ein Fenster, wo mehrere Programme enthalten sind, und ich kann nicht zwei öffnen, sondern eben konnte ich eins öffnen und seitdem gar keins mehr :oops:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  Mutex := CreateMutex(nil, True, PChar(ProgrammPfad));
  TmpLastError := GetLastError;
  if (Mutex <> 0and (TmpLastError = 0then 
  begin
    ShellExecute(0nil , PChar(ProgrammPfad), nilnil , SW_SHOWNORMAL);
  end else
  begin
     showMessage('Programm bereits gestartet!');
  end;


So sieht das nun hier aus...
hazard999
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: Mi 28.11.07 11:52 
Hallo,

erklär mal genau was du eigentlich machen willst.

Hast du eine Datei die du nicht mehrfach öffnen willst, oder sind es mehrere verschiedene
Dateien von denen immer nur eine offen sein darf oder darf nur immer eine von mehreren Dateien offen sein?

r u

René
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 11:58 
Sorry, für die schwache Erklärung am Anfang.
Also ich habe sozusagen einen Dateimanager, in dem ich mehrere Dateien habe (auch welche hinzufügen kann oder entfernen kann). Dann kann ich diese dort öffnen. Es soll jedoch jede Anwendung nur einmal gestartet werden können. Es sind also mehrere Dateien, die alle gestartet werden können, es darf jedoch jede nur ein einziges Mal gestartet sein.
D.h.:
Ich habe beispielsweise 3 Dateien.
Ich öffne Datei 1 und 2, nun bliebe mir nur noch die Möglichkeit Datei 3 zu öffnen, da die anderen schon laufen (Falls doch draufgeklickt wird: Fehlermeldung "Datei ist bereits geöffnet". Diese sollte dann auch in einem weiteren schritt in den Vordergrund geholt werden) wenn ich Datei 2 nun jedoch schließe, und sie dann wieder öffne, sollte sie auch wieder geöffnet werden können. Das heißt es soll jeweils kein Mehrfachstart der einzelnen Dateien geben. Es können jedoch beliebig viele andere Dateien hinzu aufgerufen werden.
Ich hoffe die Erklärung war besser =o)

Lieben Gruß
hazard999
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: Mi 28.11.07 12:06 
Hallo,

Ok, das geht nicht mit einem Mutex.

du brauchst eine Liste von Mutexen (ist das Deutsch?) für jede Datei einen.

und du musst dann beim schließen der Datei closeHandle für den entsprechenden Mutex aufrufen.

also

Versuchen Mutex für Programm/Datei zu erzeugen (Achtung, der Name ist wichtig, pro Programm/Datei einen
verwenden, am besten Programm/Dateiname oder fixer Text plus Zahl die du pro Versuch raufzählst.

Wenn Mutex da, dann Programm/Datei und Mutex-Handle in Liste eintragen.

Wenn Programm/Datei geschlossen wurde:

Mutex aus Liste raussuchen und closeHandle aufrufen
Eintrag aus Liste entfernen

Das einzige was wirklich tricky ist, ist heraus zu finden wann Programm/Datei zu geht.
Aber da findet sich sicher was im Forum.

r u

René
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 12:11 
Ich glaube das ganze wäre einfacher, wenn nicht variabel wäre, was für Programme im Programm sind, man kann die ja hineinschieben, wie man lustig ist, neue hinzufügen, alte herausnehmen, es ändert sich also ständig.
Muss ich mal ein wenig drüber nachgrübeln, wie das zu realisieren ist, noch fällt mir nichts ein, da ich mit Mutex auch noch nie richtig gearbeitet habe :-)
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 12:45 
Also der Mutex macht nicht das, was er machen soll.
Mein erster Ansatz (erster Post, Quellcode) hat ja alles gemacht,
bis auf die Verknüpfungen geblockt, wenn die schon offen waren,
wie bekomme ich hin, dass die auch beim zweiten öffnen ausgebremst werden?
hazard999
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 162

Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
BeitragVerfasst: Mi 28.11.07 12:52 
Der Mutex-Name ist wichtig!

Sie Posts von vorher.

Pro Name geht nur ein Mutex.

r u

René
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 28.11.07 13:00 
Wie schon erwähnt, weiß ich nicht, wie mit dem Mutex umzugehen ist, da ich noch relativ neu bin in der Programmierung. Habe mir zwar schon mehrere Beispiele durchgelesen, nur leider hat es mir nicht viel gebracht.
gispos
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 94

WIN 7
XE10, D2007
BeitragVerfasst: Sa 01.12.07 02:05 
Hallo s-hus,
mir ist aus deinen postings nicht klar um was es überhaupt geht.
1.) Das dein Programm nicht mehrfach gestartet werden kann?
2.) Das die Dateien (Anwendungen?) die Du in deinem Programm verwaltest nicht mehrfach gestartet werden können?
3.) Oder 1. + 2. ?

Gib mal bescheid
Gruß gispos
s-hus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Di 04.12.07 12:26 
Die Nr 2 ist gemeint.
Lieben Gruß.

Habe nun aber schon das Problem gelöst. Wer das gleiche Problem hat, hier meine Lösung (kann ja auch durchgeschaut werden, ob es so in Ordnung ist):

Eine Funktion eingefügt, die überprüft, ob das Programm offen ist:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function TFmHaupt.OnlyOneInstance(ProgrammPfad: String): Boolean;
var
  a: integer;
  hFile: THandle;
begin
  Result := False;
  ExpandFileName(ProgrammPfad);
  if not FileExists(ProgrammPfad) then
  begin
    Exit;
  end;
  hFile := CreateFile(pchar(ProgrammPfad), GENERIC_READ or
                      GENERIC_WRITE or GENERIC_EXECUTE, 0nil,
                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Result := hFile = INVALID_HANDLE_VALUE;
  if not Result then
  begin
    CloseHandle(hFile);
  end;
end;


und dieses wurde eingefügt, wo überprüft werden soll:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  if (OnlyOneInstance(ProgrammPfad)) then        // OnlyOneInstance prüft, ob schon eine Instanz geöffnet wurde
  begin                                          
    Showmessage('Die Datei ist in Benutzung');
  end else
  begin
    ShellExecute(0nil, PChar(ProgrammPfad), nilnil, SW_SHOWNORMAL); // falls nicht, soll sie geöffnet werden
  end;
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 04.12.07 14:24 
Hilfreich dazu ist auch die Unit [url=michael-puff.de/diri...OneInst.pas[/delphi] die ich in meinem [url=www.delphi-forum.de/...p;highlight=]Encoded SFX[/delphi] benutze (Beispielcode z.B. in meinem Projekt, welches OpenSource ist ;) ).

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.