![]() |
Neustart der Applikation aus Stabilitätsgründen...
Hallo zusammen,
ich entwickle momentan eine Applikation, welche im Dauerbetrieb stabil laufen muss. Weiterhin sind ein helles und ein dunkles Design gefordert. Da es nach dem Umschalten des Styles immer wieder zu Fehler in der VCL kommt habe ich mich für einen etwas unkonventionellen Weg entschieden. Nachdem der Benutzer das Design ändert (sollte eigentlich nicht oft vorkommen) starte ich die Applikation neu. Dazu habe ich im Hauptformular folgenden Destructor geschrieben:
Delphi-Quellcode:
Bei der Konfiguration löse ich das ganze nach einer Sicherheitsabfrage wie folgt aus:
destructor TfrmMain.Destroy;
var AppName, AppParam: string; begin inherited; if SkinChangeRestart then begin AppName := ParamStr(0); AppParam := SKIN_RESTART_PARAM; ShellExecute(0, nil, PChar(AppName), PChar(AppParam), nil, SW_SHOW); end; end;
Delphi-Quellcode:
Das funktioniert, aber ich bin mir nicht sicher, ob das der richtige Weg ist oder ob man das anders lösen sollte.SkinChangeRestart := True; Application.MainForm.Close; Ehe ein Hinweis auf "löse das VCL Problem" kommt: Ich habe ja bereits einen häufig auftretenden Fehler gemeldet (RSP-38928). Ich werde bei Gelegenheit noch einen weiteren Melden der immer wieder auftritt. Mit dem Debuggen solcher Fehler bin ich überfordert bzw. dazu fehlt mir die Zeit. Das die Anwendung in Forms dynamisch erzeugte eingebettete forms und frames enthält macht das ganze nicht leichter. Aber ehe das nicht alles seitens VCL stabil ist brauche ich eine Lösung. Die vorliegende Anwendung wird z.B. ab Oktober in Mexiko und später noch in Brasilien und den USA laufen. Da kann ich nicht mal eben hinfahren... |
AW: Neustart der Applikation aus Stabilitätsgründen...
Ich empfehle von Herrn Below die OneInstance unit (einfach mal hier danach suchen) zu benutzen. Läuft bei mir seit Jahren perfekt!
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Und genau dafür nutze ich seine Unit, naja wie dem auch sei...
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Reicht es denn nicht die Form neu zu erstellen (wobei es bei der MainForm nicht so einfach ist, das deren Freigabe standardmäßig die Anwendung beendet)
oder zumindestens die Windows-Handles/Controls neu zu generieren? |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Das Problem mit den Styles ist halt, dass manchmal Fehler direkt beim Umschalten stattfinden und manchmal erst später, wenn Frames neu aufgemacht / erzeugt werden. Meistens funktioniert es aber. Und das macht mir Bauchschmerzen. Ich hasse Fehler, die nicht reproduzierbar sind. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
sondern darum die Anwendung neu zu starten. Dafür braucht man keine extra Unit eine Zeile reicht vollkommen aus. Ich mache es beim Skin Wechsel auf diese weise.
Delphi-Quellcode:
bzw. Dein Variante sollte es auch tun. Sehe da kein Problem.
if Restart then
Result := ShellExecute(0, 'open', PWideChar(ParamStr(0)), nil, nil, SW_SHOW) |
AW: Neustart der Applikation aus Stabilitätsgründen...
offtopic
Nur um das was ich meinte zu vervollständigen, ich nutze diese nicht-gewollte unit weil diese halt möglichkeiten bietet beim zweit-aufruf schon im code die alte instanz zu schließen, neue zu starten, automatisierte aktionen ausführt etc. Klar kann man das auch alles selbst schreiben, muss man aber nicht, war halt nur ein vorschlag. habs nicht bös gemeint. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Delphi-Quellcode:
Self.RecreateWnd;
Zitat:
Bei dir nicht. Grund siehe ![]() PS: Wenn man die Anwendung inkl. der ursprünglichen Parameter neu starten will, dann siehe ![]() |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Delphi-Quellcode:
WindowState := TWindowState.wsMaximized;
BorderStyle := bsNone; BoundsRect := Screen.MonitorFromWindow(Handle).BoundsRect; |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Teste es doch einfach dann wirst du sehen das es das tut was es soll. Ohne nennenswerte Problem im Bruchteil einer Millisekunde. Es ist so schnell das es gar nicht ins Gewicht fällt oder man es merkt das die Anwendung neu gestartet wird. Wichtig ist das Ergebnis nicht die art und weise wie dieses erreicht wird. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Ich hatte eigentlich eher bedenken wann ich den Neustart durchführe. In meinem ersten Post mache ich das ja im destructor der Main. Alternativ könnte ich das ja auch hinter das "Application.Run" setzen (was ich nun auch gemacht habe...). Das ist dann der letztmöglich Zeitpunkt. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Ich arbeite ja ohne die VCL mit eigener Skinengine von daher habe ich wohl nicht so immense Initialisierung wie du. Ich schicke beim ändern des Skin aus meinen Menu
Delphi-Quellcode:
und fertig.PostQuitMessage(0); Restart := TRUE; Letztendlich zählt das Ergebnis. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Und ja: Letztendlich zählt das Ergebnis. Das Forum hilft halt bei der Meinungsfindung :-). |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Zu dem Zeitpunkt sind auch alle Forms und sonstige Komponenten der Anwendung freigegeben, was direkt nach dem Run in der Regel noch nicht der Fall ist. So eine Unit könnte in etwa so aussehen:
Delphi-Quellcode:
unit AutoRestartUnit;
interface var AutoRestart: Boolean = False; AutoRestartCmdLine: PChar; implementation uses Winapi.ShellAPI, Winapi.Windows; initialization AutoRestartCmdLine := CmdLine; finalization if AutoRestart then begin ShellExecute(0, 'open', PChar(ParamStr(0)), AutoRestartCmdLine, nil, SW_SHOW); end; end. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Du kannst einen kleinen Nagel auch mit einer Zange ins Holz hauen, also geht es sozusagen, aber dennoch ist es nicht richtig. Und genau weil zuviele so denken knallt es gern mal, sobald sich mal ein bissl was ändert. Ja, PChar entspricht aktuell PWideChar und das wird sich so schnell nicht nochmal ändern, aber da hört es nicht auf. * Integer anstatt LPARAM/WPARAM/LRESULT als Typen SendMessage/PostMessage * Interger als Cast für einen Pointer * ... |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
|
AW: Neustart der Applikation aus Stabilitätsgründen...
Delphi hängt Units nur an, wenn es der Meinung ist, etwas würde fehlen.
Was drin war, bleibt erhalten. Ausnahme: Das USES in der DPR, vor allem die Units mit IN, welches vom Projektmanager verwaltet wird. Da hier das Uses dabei komplett neu geschrieben wird, kann/wird es passieren, dass z.B. Formatierungen, Kommentare und IFDEF verloren gehen. Deine Unit muß hierbei bloß vor/über der "Forms"-Unit liegen, denn Application gibt dort im Finalization noch existierende Forms und DataModule frei. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Nehme lieber einen Fingerhut damit geht's auch. Nu dann ist die Unit von Uwe auch falsch bis auf den zusätzlichen Parameter ist es der gleiche Aufruf.
Delphi-Quellcode:
PWideChar bleibt PWideChar ob ich nun PChar übergebe und der passende Pendant vom Compiler zu gewiesen wird bleibt sich gleich.
if AutoRestart then begin
ShellExecute(0, 'open', PChar(ParamStr(0)), AutoRestartCmdLine, nil, SW_SHOW); Also verwende ich die passende Konvertierung direkt. Müßig jetzt darüber zu streiten. |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
ShellExecuteW und PWideChar mit einem UnicodeString oder WideString oder ShellExecute und PChar mit einem String. Früher dachten auch viele ShellExecute mit PAnsiChar funktioniert ja, da PChar ein PAnsiChar war. :roll: |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
Unit ShellAPI
Delphi-Quellcode:
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
Directory: PWideChar; ShowCmd: Integer): HINST; stdcall; function ShellExecute; external shell32 name 'ShellExecuteW'; |
AW: Neustart der Applikation aus Stabilitätsgründen...
Niemand hat behauptet, dass Delphi frei von Bugs sei. :stupid:
Delphi 7
Delphi-Quellcode:
Lazarus/FreePascal
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
Directory: PAnsiChar; ShowCmd: Integer): HINST; stdcall; function ShellExecute; external shell32 name 'ShellExecuteA';
Delphi-Quellcode:
{ascfun.inc} function ShellExecute(_para1:HWND; _para2:pchar; _para3:pchar;_para4:pchar; _para5:pchar;_para6:longint):HINST; external 'shell32' name 'ShellExecuteA';
sowie
Delphi-Quellcode:
{unifun.inc} function ShellExecute(_para1:HWND; _para2:LPCWSTR; _para3:LPCWSTR; _para4:LPCWSTR; _para5:LPCWSTR;_para6:longint):HINST; external 'shell32' name 'ShellExecuteW';
DevExpress (es geht auch einfacher, bzw. delphi-typischer, inkl. automatischer String-Konvertierung)
Delphi-Quellcode:
function dxShellExecute(AHandle: HWND; const AFileName: string; AShowCmd: Integer = SW_SHOWNORMAL): Boolean; overload;
Ansonsten werden natürlich für compiler-abhängige "Alias" auch die compiler-abhängigen Typen benutzt, was ja eigentlich klar sein sollte.
Code:
Im Prinzip ist es ein Übersetzungsfehler ... da Pascal/Delphi leider keine Makros oder Funktions-Aliase kennt, hätte hier der Header besser anders übersetzt werden sollen.
SHSTDAPI_(HINSTANCE) ShellExecuteA(__in_opt HWND hwnd, __in_opt LPCSTR lpOperation, __in LPCSTR lpFile, __in_opt LPCSTR lpParameters,
__in_opt LPCSTR lpDirectory, __in INT nShowCmd); SHSTDAPI_(HINSTANCE) ShellExecuteW(__in_opt HWND hwnd, __in_opt LPCWSTR lpOperation, __in LPCWSTR lpFile, __in_opt LPCWSTR lpParameters, __in_opt LPCWSTR lpDirectory, __in INT nShowCmd); #ifdef UNICODE #define ShellExecute ShellExecuteW #else #define ShellExecute ShellExecuteA #endif // !UNICODE Da Delphi selber aber keine Umschaltung zwischen ANSI und Unicode kann, gibt es hier nur auf der Entwicklerseite eventuelle Problemchen. Allerdings hat es beim anderen ShellExecuteEx hier mal richtig funktioniert.
Delphi-Quellcode:
function ShellExecuteEx(lpExecInfo: PShellExecuteInfo):BOOL; stdcall;
function ShellExecuteExA(lpExecInfo: PShellExecuteInfoA):BOOL; stdcall; function ShellExecuteExW(lpExecInfo: PShellExecuteInfoW):BOOL; stdcall; Anders sieht es z.B. beim IShellDispatch2.ShellExecute aus, denn Dieses ist explizit ausschließlich als Unicode deklariert.
Delphi-Quellcode:
[SID_IShellDispatch2]
function ShellExecute(&File: WideString; vArgs, vDir, vOperation, vShow: OleVariant): HRESULT; stdcall; |
AW: Neustart der Applikation aus Stabilitätsgründen...
Zitat:
sondern dich erst einmal auf die Gegebenheiten konzentrieren. Ich übergebe die Definitionen die seitens meines verwendeten Delphi vorgegeben sind. Ob diese letztendlich falsch sind oder nicht mag dahin gestellt sein. Darum geht es doch letztendlich. Zudem denke ich auch nicht das D2010 noch in irgendeiner weise Aktualisierungen bekommen wird. Somit dürften alle Unklarheiten beseitigt sein. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:43 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