![]() |
Problem mit Dateiaufruf per paramstr
Also folgendes Problem:
Habe ein programm das sich im Contextmenü einträgt. Wenn ich eine Datei über den Eintrag im CMenü auswähle startet mein Programm 1x und hat im paramstr(1) den Pfad zur Datei die gewählt wurde... Wenn ich mehr als eine datei aufrufe sollen diese natürlich auch von meinem programm geöffnet werden mein programm startet aber bei 3 dateien dann 3x ??? es soll aber nur 1x starten und die anderen dateien ebanfalls bearbeiten... Lösungsansatz: das Programm darf nur einmal starten und muss wenn es bemerkt das es mehrfach gestartet wurde sich selbst beenden und den jeweiligen paramstr(1) an das ersdte gestartet programm senden
Code:
// ===================================================
Initialization mHandle:=CreateMutex(nil,True,'my_programm'); if GetLastError=ERROR_ALREADY_EXISTS then begin // hier die Daten senden ??? wenn ja wie ? Halt; end; finalization if mHandle<>0 then CloseHandle(mHandle) end. Danke für Eure Hilfe :spin: |
Re: Problem mit Dateiaufruf per paramstr
Delphi-Quellcode:
Unter Win9x werden Mutexe/Atome/Semaphore usw. nicht mehr korrekt freigeben falls die Anwednung crasht. Dadurch könnte es passieren das eine einmal gecrashte Anwendung nicht erneut gestartet werden kann, da der globale benammte Mutex noch existiert. ABER!, das feine ist das Fensterhandles auch unter Win9x ungültig werden wenn die Anwendung gecrasht ist. Deshalb nutzen wir oben ein Fensterhandle mit möglichst eindeutigen Namen um 1. zu erkennen ob unsere Anwendung schon läuft und 2. gleichzeigt als Transportweg um ParamStr(1) zu übertragen.const cMagic = $1234567; cResult = $7654321; sTitle = 'my_program$XY12345678_Moeglichst_Eindeutiger_Name'; // als sTitle kann auch ParamStr(0) herhalten var WndHandle: hWnd = 0; type TSingleInstance = class class procedure WndProc(var Msg: TMessage); class procedure Start; class procedure Stop; end; class function TSingleInstance.WndProc(var Msg: TMessage); var Param: String; begin with Msg do if (Msg = wm_CopyData) and (PCopyDataStruct(lParam).cwData = cMagic) then begin Param := PCopyDataStruct(lParam).lpData; OpenFile(Param); // o.ä. Result := cResult; end else Result := DefWindowProc(WndHandle, Msg, wParam, lParam); end; class procedure TSingleInstance.Start; var PrevWnd: hWnd; Data: TCopyDataStruct; Param: String; begin PrevWnd := FindWindow('TPUtilWindow', sTitle); if IsWindow(PrevWnd) then begin Param := ParamStr(1); Data.cwData := cMagic; Data.cbData := Length(Param) +1; Data.lpData := Pointer(Param); if SendMessage(PrevWnd, wm_CopyData, 0, Integer(@Data)) = cResult then ; // erfolgreich Halt; end; WndHandle := AllocateHWnd(WndProc); SetWindowText(WndHandle, sTitle); end; class procedure TSingleInstance.Stop; begin if IsWindow(WndHandle) then DeallocateHWnd(WndHandle); end; initialization TSingleInstance.Start; finalization TSingleInstance.Stop; end; Allerdings auch diese Methode hat ihre Nachteile, z.b. bei Services die in einer anderen WinSta laufen. Gruß Hagen PS: obiger Code ist nur aus'm Gedächtnis, also keine Garantie das alles absolut korrekt ist ;) |
Re: Problem mit Dateiaufruf per paramstr
Kommt so erst mal in die Code-Lib. Irgendwelche Vorschlage für eine Überschrift, die kurz und aussagekräftig ist?
@Hagen: Das mit dem Schlüsselwort class vor den Methoden der Klasse sehe ich zum ersten mal. Dient das nur der Lesbarkeit oder hat das noch einen tieferen Sinn? |
Re: Problem mit Dateiaufruf per paramstr
wäre jemand so nett den source oben etwas näher zu erläutern ??
ich will ihn nicht nur kopieren sondern auch verstehen :) danke ... |
Re: Problem mit Dateiaufruf per paramstr
[Fehler] Unit1.pas(101): Funktion benötigt Ergebnistyp
[Fehler] Unit1.pas(106): Undefinierter Bezeichner: 'cwData' [Warnung] Unit1.pas(106): Der Vergleich ergibt immer Falsch [Fehler] Unit1.pas(108): Inkompatible Typen: 'String' und 'Pointer' [Fehler] Unit1.pas(109): Inkompatible Typen: 'String' und 'PChar' [Fehler] Unit1.pas(121): Inkompatible Typen: 'String' und 'PChar' [Fehler] Unit1.pas(125): Undefinierter Bezeichner: 'cwData' [Warnung] Unit1.pas(131): Symbol 'AllocateHWnd' wird abgelehnt [Warnung] Unit1.pas(137): Symbol 'DeallocateHWnd' wird abgelehnt [Fataler Fehler] filekiller.dpr(5): Verwendete Unit 'Unit1.pas' kann nicht compiliert werden |
Re: Problem mit Dateiaufruf per paramstr
Das muß dwData heißen.
Den String kannst du einfach nach PChar casten. Desweiteren helfen uns deine Zeilennummern nicht wirklich. Gib mal die Stellen im Code an. |
Re: Problem mit Dateiaufruf per paramstr
ich glaube ich weiß wo mein problem liegt ...
ich will das eine *.exe einzelne dateien als auch mehrere datein löschen kann... wenn ich das versuche mit den hier genannten beispielen zu lösen passiert folgendes: 3 Dateien ausgewählt -> myprogramm.exe startet 3x exe1 heisst 'myprogramm' soll da bleiben und daten von 2,3 empfangen exe2 heisst 'myprogramm' soll paramstr(1) an 1 exe senden + schliessen exe3 heisst 'myprogramm' soll paramstr(1) an 1 exe senden + schliessen und genau da ist das problem, in dem moment wenn ich sende sind läuft mein programm mehr als 1 mal... wie kann ich das lösen ? |
Re: Problem mit Dateiaufruf per paramstr
@wb32: so wie oben angedeutet. Der Source ist allerdings eben aus dem Gedächtnis und NICHT garantiert lauffähig.
@Lucki: Ich werde den Source lieber nochmal überarbeiten, so daß er auch tatsächlich funktioniert (per Copy&Paste, war aber eigentlich nicht so gedacht von mir :) Zur Frage mit dem Klassen Methoden -> class function ... Ja dies ist absolut notwendig, zumindestens für class procedure WndProc(). Diese Deklaration ist Typkompatibel mit TWndMethod die ja in AllocateHWnd(TSingleInstance.WndProc) benötigt wird. Normalerweise deklarieren wir ein TObject mit procedure WndMethod(), erzeugen ein solches Object um dann AllocateHWnd(MyObject.WndProc) benutzen zu können. Wir müssten im Normalfall also immer eine Objectinstance erzeugen. Um dies nicht machen zu müssen gibt es zwei Wege: 1.) über den obigen Klassenmethoden Weg oder 2.) über ein getürktes Event bei TMethod(Event).Code := @Procedure. Der Weg über Klassenmethoden ist aber sauberer. Um nun alles noch sauberer zu kapseln habe ich gleich noch die Methoden .Start und .Stop als Klassenmethode deklariert. Gruß Hagen |
Re: Problem mit Dateiaufruf per paramstr
also ich hab folgende idee...
1 programmstart form1.caption:='myprogramm'; dann prüfen ob mehrfachstart vorliegt 2,3,4,5,6 form1.caption:='xxxxxxxxx'; dann einfach an 'myprogramm' senden... geht das so ? irgendwas stimmt am source aber nicht...
Code:
was stimmt da nicht ?
procedure TForm1.FormShow(Sender: TObject);
begin if ParamCount > 0 then begin Form1.Caption:= 'myprogramm'; mHandle := CreateMutex(nil,True, 'myprogram_45zg556z5g43'); Memo1.Lines.Add(SysErrorMessage(GetLastError)); // das funktioniert if GetLastError=ERROR_ALREADY_EXISTS then begin // das funktioniert nicht Form1.Caption:= 'xxxxxxxxx'; end; end; |
Re: Problem mit Dateiaufruf per paramstr
ok ich glaube ich habs, die funktion getlaserror ist nach dem aufruf leer richtig ?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz