| Autor |
Beitrag |
woully
      
Beiträge: 78
|
Verfasst: Mi 30.09.09 18:09
Hallo,
folgender Abschnitt :
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:
| Type TM_UPDATECFENTER = Class ... Procedure WMUSERUPDINSTALL(var msg : TMessage);message WM_USERUPDINSTALL; ... end;
Procedure TM_UPDATECENTER.WMUSERUPDINSTALL(var msg : TMessage); Begin MessageDlg('Empfangen',mterror,[Mbok],0,0); end;
var updHandle : THANDLE; m_Handle : THANDLE; Initialization
if paramcount > 0 then Begin updHandle := FindWindowEx(0,0,PChar('TM_UPDATECENTER'),pchar('medavis starter')); if updHandle <> 0 then SendMessage(updHandle,WM_USERUPDINSTALL,0,0); mHandle := CreateMutex(nil,True,'medavisstarter'); if GetLastError = ERROR_ALREADY_EXISTS then halt;
Finalization if mHandle <>0 then closeHandle(mHandle); |
Also,
meine Anwendung wird ein erstesmal gestartert.
Wenn die Anwendung erneut gestartet wird, und einen Start Parameter enthält, soll eine Botschaft mit Sendmessage, der Ersten gestartet Instanz gesendet werden.
Die Botschaft wird erfolgreich versendet, wird aber nie Empfangen...
So. Beende ich dann die Anwendung (erste Instanz), starte Sie erneut, starte eine Zweite Instanz mit Startparameter, dann bekomme ich die Meldung "Empfangen"
Was mache ich falsch ? Warum funktioniert das ganze erst nachdem die Anwendung einmal geschlossen wurde, und erneut gestartet??
Danke
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Mi 30.09.09 18:22
woully hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| if paramcount > 0 then Begin updHandle := FindWindowEx(0,0,PChar('TM_UPDATECENTER'),pchar('medavis starter')); <span style="color: red"> if updHandle <> 0 then SendMessage(updHandle,WM_USERUPDINSTALL,0,0); <span style="color: red"> mHandle := CreateMutex(nil,True,'medavisstarter'); if GetLastError = ERROR_ALREADY_EXISTS then halt;
Finalization if mHandle <>0 then closeHandle(mHandle); |
|
Kein Wunder, das Mutex - Objekt wird ja erst erstellt wenn eine Anwendung mit Parameter gestartet wird. also wenn ich Dich richtig verstanden habe bei 2. Aufruf
Sicher das Du das "Begin" da haben willst?
Grüsse, Dirk
|
|
woully 
      
Beiträge: 78
|
Verfasst: Mi 30.09.09 20:08
Hi,
schei..
Naturlich nicht... Copy Paste Problem sorry...
hier der Korrekte Abschnitt :
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:
| Type TM_UPDATECFENTER = Class ... Procedure WMUSERUPDINSTALL(var msg : TMessage);message WM_USERUPDINSTALL; ... end;
Procedure TM_UPDATECENTER.WMUSERUPDINSTALL(var msg : TMessage); Begin MessageDlg('Empfangen',mterror,[Mbok],0,0); end;
var updHandle : THANDLE; m_Handle : THANDLE; Initialization
if paramcount > 0 then Begin updHandle := FindWindowEx(0,0,PChar('TM_UPDATECENTER'),pchar('medavis starter')); if updHandle <> 0 then SendMessage(updHandle,WM_USERUPDINSTALL,0,0); end;
mHandle := CreateMutex(nil,True,'medavisstarter'); if GetLastError = ERROR_ALREADY_EXISTS then halt;
Finalization if mHandle <>0 then closeHandle(mHandle); |
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 480
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 30.09.09 21:17
Ich glaube, dass dein Ansatz verkehrt ist. Schau dir mal die Unit OneInst bei Luckies Importe an.
Ansatz dort: Im Initialization ein Mutex erzeugen. Wenn dabei ein Fehler auftritt (d.h. Anwendung läuft bereits), dann eine Message Broadcasten, die vorher per RegisterWindowMessage registriert wurde und daher eindeutig ist (wenn das mehrere Anwendungen machen, wird immer dieselbe Message-ID geliefert). Diese Message sollte dann nur deine Anwendung kennen/verarbeiten, und das eigene Fensterhandle zurückliefern. An dieses leitest du dann die Parameter weiter.
Die ganze Arbeit nimmt die Unit für dich ab - du must nur den Messagehandler für die Broadcast-Message implementieren und die Parameter-Annahme.
_________________ We are, we were and will not be.
|
|
woully 
      
Beiträge: 78
|
Verfasst: Do 01.10.09 09:44
Hallo
Gausi,
ich habe meine Software an Luckies Beispiel angepasst.
Leider ohne Erfolg.
Die Software verhält die Botschaft wird immer noch nicht empfangen....

|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Do 01.10.09 09:48
Mal ne Frage: Welches Betriebssystem verwendest du?
Edit: Wenn es Vista ist, dann kann es sein, dass das mit den Messages nicht funktioniert.
Das Programm hat "Update" im Namen. Wird also nur mit Admin-Berechtigung ausgeführt. Unter Vista können keine Botschaften an Fenster von Programmen mit höherer Berechtigung geschickt werden.
Beste Grüße
Zuletzt bearbeitet von Tastaro am Do 01.10.09 09:57, insgesamt 1-mal bearbeitet
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 480
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Do 01.10.09 09:50
_________________ We are, we were and will not be.
|
|
woully 
      
Beiträge: 78
|
Verfasst: Do 01.10.09 09:56
humm,
ich hoffe zumindest das ich was falsch mache.. Das würde ja bedeuten das es eine lösung gibt...pff
So, gute Frage Tastaro.. Ich verwende Vista Ultimate...
Noch nä Info.. Mit abgeschalteter UAC funktionniert das ganze...

|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Do 01.10.09 10:22
Dann ist es der von mir beschriebene Effekt.
Man kann keine Botschaften an Fenster mit höherer Berechtigung schicken.
Beste Grüße
|
|
woully 
      
Beiträge: 78
|
Verfasst: Do 01.10.09 10:23
so,
ich habe meine Klasse umbennennt in TM_STARTERCENTER..
Auch ohne Erfolg...
Ich habe noch einige Variablen die das Wort update enthalten z.B. m_boAllowUpdate ..
Ich hoffe doch nicht das ich die auch alle umbennen muss wegen diesem beschies... Vista.
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Do 01.10.09 10:30
Der Name der Klasse ist egal. Wichtig ist der Name des Projekts an das du schickst und der Titel des Fensters. Ausßerdem noch der Inhalt der Projekteigenschaften.
"Böse" Worte sind z.B. "Update", "Setup" und "Install".
Beste Grüße
|
|
woully 
      
Beiträge: 78
|
Verfasst: Do 01.10.09 10:47
ok,
so weit so gut dann..
Leider funktionniert es nicht.
Hätte ich eigentlich gleich wissen müssen,
da das ganze funktionniert wenn alle Instanzen beendet wurden, und das ganze nochmal gestartet wird...
Das ist echt zum verzweifeln.
|
|
woully 
      
Beiträge: 78
|
Verfasst: Fr 02.10.09 17:05
Hat sonst niemand nä idee ???
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 02.10.09 17:35
|
|
woully 
      
Beiträge: 78
|
Verfasst: Mo 05.10.09 17:31
ja,
idee könnte funktionieren.
Ich setze es mal um..
Danke
|
|
woully 
      
Beiträge: 78
|
Verfasst: Di 06.10.09 12:36
ok,
ich habe jetzt auf MemoryMappedFiles umgestellt.
Funktionniert wie gewollt. Ist zwar umständlicher als Sendmessage, aber es funktioniert.
Trotzdem, falls jemand eine erklärung hätte, zu der nicht funktionnierende Sendmessage Funktion, würde es mich auch interessieren.
Danke für eure Mühe.
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 06.10.09 20:50
Alternative: GlobalEnvironment
Info: edn.embarcadero.com/article/28254
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: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103:
| uses Registry;
function SetGlobalEnvironment2(const Name, Value: string; const User: Boolean = True): Boolean; const KeyName = 'Environment'; REG_MACHINE_LOCATION = 'System\CurrentControlSet\Control\Session Manager\' + KeyName; REG_USER_LOCATION = KeyName;
var {$IFDEF CLR} NamePtr: IntPtr; {$ENDIF} AResult: DWORD; begin with TRegistry.Create do try if User then begin Result := OpenKey(REG_USER_LOCATION, True); end else begin RootKey := HKEY_LOCAL_MACHINE; Result := OpenKey(REG_MACHINE_LOCATION, True); end; if Result then begin WriteString(Name, Value); {$IFDEF CLR} SetEnvironmentVariable(Name, Value); {$ELSE} SetEnvironmentVariable(PChar(Name), PChar(Value)); {$ENDIF} {$IFDEF CLR} NamePtr := Marshal.StringToHGlobalAuto(KeyName); SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, WPARAM(NamePtr), SMTO_NORMAL, 1000, AResult); Marshal.FreeHGlobal(NamePtr) {$ELSE} SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, WPARAM(PChar(KeyName)), SMTO_NORMAL, 1000, AResult); {$ENDIF} end; finally Free; end; end;
function GetGlobalEnvironment2(const Name: string; const User: Boolean = True): String; var b:Boolean; resourcestring REG_MACHINE_LOCATION = 'System\CurrentControlSet\Control\Session Manager\Environment'; REG_USER_LOCATION = 'Environment'; begin with TRegistry.Create do try if User then b:=OpenKey(REG_USER_LOCATION, True) else begin RootKey := HKEY_LOCAL_MACHINE; b:=OpenKey(REG_MACHINE_LOCATION, True); end; if b then begin Result:=ReadString(Name); end; finally Free; end; end;
procedure TForm1.Button1Click(Sender: TObject); var Name, Value2 : String; begin Name:= mystr; Value2:= 'HATHOR'; SetGlobalEnvironment2(Name, Value2); end;
procedure TForm1.Button2Click(Sender: TObject); begin Label1.caption:=GetGlobalEnvironment2(mystr); end;
procedure TForm1.Button3Click(Sender: TObject); var Name, Value2 : String; begin Name:= mystr; Value2:= ''; SetGlobalEnvironment2(Name, Value2); end; |
|
|
|