Autor |
Beitrag |
s-hus
      
Beiträge: 17
|
Verfasst: 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:
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, 0, nil, 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(0, nil, PChar(ProgrammPfad), nil, nil , SW_SHOWNORMAL); end; |
Dieses ist der Teil, der den Mehrfachstart unterbinden soll.
Ich hoffe ihr könnt mir helfen
Einen lieben Gruß.
|
|
hazard999
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: 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)
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 <> 0) and (TmpLastError = 0) then begin end else showMessage('Programm bereits gestartet!');
und beim Programm beenden
if (Mutex <> 0) then CloseHandle(Mutex); |
r u
René
Moderiert von Tino: Code- durch Delphi-Tags ersetzt
|
|
s-hus 
      
Beiträge: 17
|
Verfasst: Mi 28.11.07 11:30
Mit einem Mutex hatte ich es auch schon probiert, aber leider Probleme beim einbauen in den Code gehabt 
|
|
s-hus 
      
Beiträge: 17
|
Verfasst: 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
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| Mutex := CreateMutex(nil, True, PChar(ProgrammPfad)); TmpLastError := GetLastError; if (Mutex <> 0) and (TmpLastError = 0) then begin ShellExecute(0, nil , PChar(ProgrammPfad), nil, nil , SW_SHOWNORMAL); end else begin showMessage('Programm bereits gestartet!'); end; |
So sieht das nun hier aus...
|
|
hazard999
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: 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 
      
Beiträge: 17
|
Verfasst: 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
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: 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 
      
Beiträge: 17
|
Verfasst: 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 
      
Beiträge: 17
|
Verfasst: 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
      
Beiträge: 162
Win XP SP2
VS 2010 Ultimate, CC.Net, Unity, Pex, Moles, DevExpress eXpress App
|
Verfasst: 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 
      
Beiträge: 17
|
Verfasst: 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
      
Beiträge: 94
WIN 7
XE10, D2007
|
Verfasst: 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 
      
Beiträge: 17
|
Verfasst: 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:
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, 0, nil, 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| if (OnlyOneInstance(ProgrammPfad)) then begin Showmessage('Die Datei ist in Benutzung'); end else begin ShellExecute(0, nil, PChar(ProgrammPfad), nil, nil, SW_SHOWNORMAL); end; |
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: 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  ).
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
|