![]() |
Alle resourcestrings der aktuellen Exe auflisten
Hallo,
Ist es irgendwie möglich die Liste aller Resourcestrings die im Sourcecode angeführt sind zu bekommen? Meine Idee: Alle Fehlermeldungen im Programm werden mittels Resourcestring deklariert (damit schön mit SiSulizer übersetzbar). Der Benutzer bekommt vom Exceptionhandler den Identifier des Resourcestrings als Fehlernummer angezeigt. Ich brauche jetzt ein Mapping von allen Resourcestrings auf die Identifier (und/oder zurück), damit ich von der Fehlernummer aus erkennen kann welcher Resourcestring es war, und welche Stelle im Sourcecode betroffen ist. Gibt es dafür eine Lösung? Danke und lg Marius |
Re: Alle resourcestrings der aktuellen Exe auflisten
Nein geht nicht direkt.
Die einfachste Lösung ist es am Anfang des Strings selber eine Nummer zu speichern. Also so
Delphi-Quellcode:
Bei jedem Zugriff auf einen Resourcestring ist der String ein normaler LongString. Also zum Zeitpunkt wenn die Exception diesen String übergeben bekommt ist es ein LongString und es existiert keine Verbindung mehr zu einer Resource. Das "Laden" der Resourcestrings macht der Laufzeitcode vollständig transparent. Also schon während der Laufzeit wurden die Resourcestring in LongString quasi geladen und konvertiert. Das macht der RTL Code auf Anlass des Compilers zum Zeitpunk der Initialisierung einer Unit, also bevor die Initialization Sektion der Unit aufgerufen wird. Egal ob im Source auch Initialization steht oder nicht, eine Unit hat diese "Initialization Funktion" immer. Und davor werden die Resourcestring real geladen in LongStrings.
resourcestring
sFehler = '123: Fehler bei XYZ aufgetreten'; Davon abgesehen gilt folgendes: Jeder String der als Resource gespeichert wurde bekommt eine eindeutige ID. Die Vergabe dieser ID macht der Linker vollständig transparent für uns. Dh. jedesmal nach der Deklaration eines neuen Resourcestrings ändern sich ALLE IDs dieser Strings in der Resource. Ein Resourcestring hat also aus Sicht des Programmieres in Delphi keine vorhersagebare und immer gleiche ID in der String-Resource der EXE. Es gibt einen Weg, definitiv, aber der würde nahe an einem Hack liegen. Der RTL Code der einen Resourcestring lädt muß ja selber wissen welche Resource-ID in der String-Resource der EXE diesem zugeordnet ist. Dazu speichert der Linker eine Tabelle zum Resourcestring ab in der eine Basis-ID drinnensteht. Man kann über Zeigerarithmetik an diese "Tabelle" rankommen und so auch an die IDs der Resourcestrings. Damit weist DU aber eben noch nicht welcher reale String, eg. Text, sich hinter dieser ID verbirgt. Kompiliert man neu so kann es durchaus sein das sich diese ID zum Text ändert. [edit] Schau mal in Unit System.pas, da findest du
Delphi-Quellcode:
Der Resourcestring wird also als Zeiger vom Typ PResStringRec angesprochen, eg. konvertiert. Das Member .Indetifier enthält entwerder die reale Resource ID des zugehörigen Strings aus der Resource der EXE oder den LongString selber. Sollte .Identifier < $10000 sein, sprich das höherwertige Word des Cardinals = 0 sein, so ist es eine Resource ID. Der String muß dann aus der EXE geladen werden. Danach wird .Identifier aber als Zeiger eines LongString abgesprochen. Dh. beim Zugriff auf einen Resourcestring wird nur beim 1. mal der String aus der EXE geladen, danach steht er fertig im Speicher und wird nicht mehr nachgeladen.
type
PResStringRec = ^TResStringRec; TResStringRec = packed record Module: ^Longint; Identifier: Integer; end; procedure Test; resourcestring sTest = 'Test String Resource'; var Msg: PResStringRec; begin Msg := @sTest; ShowMessage(LoadResString(Msg)); end; Schau dir die Implementierung in Unit System.pas von LoadResString() genauer an. [/edit] Gruß Hagen |
Re: Alle resourcestrings der aktuellen Exe auflisten
hallo,
wow, vielen dank für die ausführliche Antwort! den code in den string einzuspeichern wäre eine idee, aber dann kann er auch lokalisiert werden, das möchte ich nicht dass der dolmetscher da was ändern kann leider wird meine frage nicht beantwortet wie ich die liste aller Resourcestring-IDs meiner exe bekommen kann. sowas wie GetAllResourceStrings ist glaube ich nicht möglich. das problem habe ich nun folgendermassen gelöst: ich habe nun eine eigene Exceptionklasse implementiert die als Parameter einen Pointer auf einen Resourcestring überimmt.
Delphi-Quellcode:
der Exceptionhandler gibt den Identifier im Messagedialog aus.
constructor EResException.Create(const ResString: PResStringRec; const Postfix: String = '');
begin Message := LoadResString(ResString)+Postfix; Identifier := ResString.Identifier; end; inzwischen habe ich herausgefunden dass delphi entsprechend konfiguriert ein .drc file generiert. dort steht alles was ich brauche (Automatisch vergebener Identifier - für mich nun die Fehlernummer, resourcestringname, originalwert): #define FHaupt_S_FHAUPT_OUTLOOK_KANN_NICHT_GESTARTET_WERDE N 64131 FHaupt_S_FHAUPT_OUTLOOK_KANN_NICHT_GESTARTET_WERDE N, "Outlook kann nicht gestartet werden" zu einer exe kann ich also aus dem .drc file den zugehörigen resourcestring raussuchen, sowie die original-fehlermeldung lg marius |
Re: Alle resourcestrings der aktuellen Exe auflisten
Zitat:
Schau dir mal ResString.Identifier im Debugger mal VOR und NACH den Aufruf von LoadResString() an. Gruß Hagen |
Re: Alle resourcestrings der aktuellen Exe auflisten
Guten Morgen Marius,
Zitat:
Grüße vom marabu |
Re: Alle resourcestrings der aktuellen Exe auflisten
na bum
negaH: sorry, habe beim ersten Lesen nicht ganz verstanden. jetzt ist es mir klar ResXplor würde mir helfen die resourcestrings aus der exe zu laden. Seht Ihr aber eine Möglichkeit in meiner Exceptionklasse irgendwie (auch nach dem ersten Zugriff) zu einem übergebenen PResStringRec auf den Identifier ranzukommen und damit die Exceptionklasse funktionsfähig zu machen? Wenn ich irgendwie die Tabelle aller ResourceStrings hätte, könnte ich beim Programmstart mir die Identifier merken... Ideen? |
Re: Alle resourcestrings der aktuellen Exe auflisten
Du möchtest deine Strings mit einer immer absoluten ID vergeben, als Fehlernummer. Bau es in den String selber ein, setzte nach der Nummer ein Doppelpunkt, in deiner Exception Klasse entferntst du diese Nummer, wenn du es als unschön empfindest. Eine Zahl aus dem Deutschen ins Russische/Japanische/usw. übersetzt erbigt die gleiche Zahl.
Geschätzter Aufwand: 10 Minuten. Es gibt für alles eine Lösung, aber bei den ResourceStrings keine einfache. Die IDs verändern sich ständig also muß man die *.DRC Datei parsen. Der Konstanten Name ist immer gleich aber nicht dessen ID. Gruß Hagen |
Re: Alle resourcestrings der aktuellen Exe auflisten
die fehlernummern selbst zu vergeben möchte ich vermeiden. es geht um die umstellung eines grossen projekts. da ist der aufwand alles umzustellen und die fehlernummern zu verwalten recht gross. die lösung die intern vergebenen IDs der resourcestrings zu verwenden finde ich sehr elegant. dass sich damit die "fehlernummern" bei jeder release ändern stört mich nicht.
das einzige was fehlt ist immer zu einem resourcestring PResStringRec die entsprechende ID herausfinden zu können (auch beim zweiten aufruf des resourcestrings). Zitat:
gruss marius |
Re: Alle resourcestrings der aktuellen Exe auflisten
Ich denk mal drüber nach, denke schon das man eine automatisierte Lösung finden kann.
Gruß Hagen |
Re: Alle resourcestrings der aktuellen Exe auflisten
[quote="negaH"]
Zitat:
gruss marius |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:53 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